स्विफ्ट में, एसिंक्रोनस कोड के लिए OperationQueue
उपयोग करना बिल्कुल नरक जैसा लग सकता है क्योंकि, हुड के तहत, यदि उनके सिंक्रोनस कोड का संकलन पूरा हो जाता है तो Operations
पूर्ण माना जाता है।
दूसरे शब्दों में, नीचे वर्णित उदाहरण को संकलित करने से एक टूटा हुआ निष्पादन आदेश आउटपुट होगा, क्योंकि जब तक एसिंक्रोनस कोड निष्पादित होता है, तब तक Operation
पहले ही पूरा हो चुका होगा।
let operationQueue = OperationQueue() operationQueue.maxConcurrentOperationCount = 1 operationQueue.addOperation { DispatchQueue.main.asyncAfter(deadline: .now() + 1) { print("First async operation complete") } print("First sync operation complete") } operationQueue.addOperation { DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { print("Second async operation complete") } print("Second sync operation complete") }
यह कोड प्रिंट होगा:
First sync operation complete Second sync operation complete First async operation complete Second async operation complete
हालाँकि, इन प्रतिबंधों से बचने का एक तरीका है। यह समझने के लिए कि समस्या को कैसे हल किया जाए, आपको यह समझने की आवश्यकता है कि Operation
हुड के तहत कैसे काम करता है।
Operation
में स्वयं चार झंडे हैं जिनके द्वारा आप ऑपरेशन के जीवन चक्र को ट्रैक कर सकते हैं:
isReady
- इंगित करता है कि इस समय Operation
किया जा सकता है या नहीं।
isExecuting
यह दर्शाता है कि कोई Operation
वर्तमान में प्रगति पर है या नहीं।
isFinished
- यह दर्शाता है कि Operation
वर्तमान में पूरा हो गया है या नहीं।
isCancelled
- इंगित करता है कि क्या Operation
रद्द कर दिया गया था।
सिद्धांत रूप में, Operation
अतुल्यकालिक रूप से निष्पादित होने से पहले Operation
isFinished
स्थिति में प्रवेश करता है, इसलिए हमें एक ऐसी तकनीक विकसित करने की आवश्यकता है जिसके द्वारा हम Operation
के जीवन चक्र में हेरफेर करने में सक्षम होंगे।
इस संभावना को Operation
उपवर्गित करके और start
/ cancel
तरीकों को फिर से परिभाषित करके, साथ ही उन सभी झंडों को, जिन पर ऑपरेशन का जीवन चक्र बनाया गया है, हल किया जा सकता है।
यहाँ कोड है:
public class AsyncOperation: Operation { // MARK: Open override open var isAsynchronous: Bool { true } override open var isReady: Bool { super.isReady && self.state == .ready } override open var isExecuting: Bool { self.state == .executing } override open var isFinished: Bool { self.state == .finished } override open func start() { if isCancelled { state = .finished return } main() state = .executing } override open func cancel() { super.cancel() state = .finished } // MARK: Public public enum State: String { case ready case executing case finished // MARK: Fileprivate fileprivate var keyPath: String { "is" + rawValue.capitalized } } public var state = State.ready { willSet { willChangeValue(forKey: newValue.keyPath) willChangeValue(forKey: state.keyPath) } didSet { didChangeValue(forKey: oldValue.keyPath) didChangeValue(forKey: state.keyPath) } } }
Operation
से हमें प्राप्त उपवर्ग बुनियादी है और हमें इसे बलपूर्वक मैन्युअल रूप से पूरा करने की अनुमति देता है।
पूर्णता ब्लॉकों के साथ काम करने के लिए, आपको एक और उपवर्ग बनाना चाहिए। हालाँकि, यह Operation
का उपवर्ग नहीं होगा, बल्कि AsyncOperation
का होगा।
public typealias VoidClosure = () -> Void public typealias Closure<T> = (T) -> Void public class CompletionOperation: AsyncOperation { // MARK: Lifecycle public init(completeBlock: Closure<VoidClosure?>?) { self.completeBlock = completeBlock } // MARK: Public override public func main() { DispatchQueue.main.async { [weak self] in self?.completeBlock? { DispatchQueue.main.async { self?.state = .finished } } } } // MARK: Private private let completeBlock: Closure<VoidClosure?>? }
यह उपवर्ग हमें Operation
को बंद करने की अनुमति देगा, जिसके बाद Operation
पूरा हो जाएगा।
आइए इस प्रकार के ऑपरेशन को व्यवहार में आज़माएँ:
let operationQueue = OperationQueue() operationQueue.maxConcurrentOperationCount = 1 operationQueue.addOperation( CompletionOperation { completion in DispatchQueue.main.asyncAfter(deadline: .now() + 1) { print("First async operation complete") completion?() } print("First sync operation complete") } ) operationQueue.addOperation( CompletionOperation { completion in DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { print("Second async operation complete") completion?() } print("Second sync operation complete") } )
परिणामस्वरूप, हम Operations
के समकालिक निष्पादन को प्राप्त करने में सक्षम थे:
First sync operation complete First async operation complete Second sync operation complete Second async operation complete
मुझसे संपर्क करने में संकोच न करें
यहाँ भी प्रकाशित किया गया