paint-brush
ऑपरेशनक्यू + एसिंक्रोनस कोड: वह सब कुछ जो आपको जानना आवश्यक हैद्वारा@bugorbn
532 रीडिंग
532 रीडिंग

ऑपरेशनक्यू + एसिंक्रोनस कोड: वह सब कुछ जो आपको जानना आवश्यक है

द्वारा Boris Bugor5m2024/03/17
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

स्विफ्ट में, सिंक्रोनस कोड के लिए ऑपरेशन कतार का उपयोग करना बिल्कुल नर्क जैसा लग सकता है क्योंकि, हुड के तहत, यदि उनके कोड का संकलन पूरा हो जाता है तो कोड को पूर्ण माना जाता है। जब तक एसिंक्रोनस कोड निष्पादित होता है, तब तक `ऑपरेशन` पहले ही पूरा हो चुका होगा। यह समझने के लिए कि समस्या को कैसे हल किया जाए, आपको यह समझने की आवश्यकता है कि ऑपरेशन का जीवन चक्र कैसे काम करता है।
featured image - ऑपरेशनक्यू + एसिंक्रोनस कोड: वह सब कुछ जो आपको जानना आवश्यक है
Boris Bugor HackerNoon profile picture

स्विफ्ट में, एसिंक्रोनस कोड के लिए 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


मुझसे संपर्क करने में संकोच न करें ट्विटर यदि आपके कोई प्रश्न हैं तो। इसके अलावा, आप हमेशा कर सकते हैं मेरे लिए एक कॉफ़ी खरीदो .


यहाँ भी प्रकाशित किया गया