दिलचस्प पोस्ट
कई तत्वों को परिवर्तित करने के लिए डीसी 2बीन फ़ंक्शन का तेज़ संस्करण? उन्हें जोड़ने के बाद दूरस्थ रिपॉजिटरी से निर्देशिका को निकालें। Gitignore एक jQuery UI संवाद में डेटा पास करना MySQL "के साथ" खंड जावा के माध्यम से सीएमडी आज्ञाओं को कैसे कार्यान्वित करें सबसे व्यापक रूप से इस्तेमाल किए जाने वाले C ++ वेक्टर / मैट्रिक्स गणित / रैखिक बीजगणित पुस्तकालयों, और उनकी लागत और लाभ व्यापार का क्या होता है? Android में गतिविधियों के बीच तार पास करना C # में एक बड़ी स्ट्रिंग में एक सबस्ट्रिंग के सभी पदों को ढूँढना मैं "IllegalStateException: स्क्रॉल्यूव्यू केवल एक सीधा बच्चे की मेजबानी कर सकता हूं" से कैसे बच सकता हूं? डेटा फ्रेम में जेसन डेटा आयात करना किसी वेब ऐप से मूल आईओएस एप कैसे खोल सकता है अजगर – यदि एक सूची दूसरे का एक सबसेट है तो यह सत्यापित करना मैं आईएसओ -8859-1 को जावास्क्रिप्ट स्ट्रिंग कैसे ट्रांसकोड करूं? IPhone पर JSON दिनांक को पार्स करना एक फाइल reparse करने के लिए Logstash मजबूर करने के लिए कैसे?

NSBlockOperation को कैसे रद्द करें

मेरे पास लंबे समय तक चलने वाला लूप है जो मैं एक NSOperation साथ पृष्ठभूमि में चलाना चाहता हूं। मैं एक ब्लॉक का उपयोग करना चाहता हूं:

 NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ while(/* not canceled*/){ //do something... } }]; 

सवाल यह है कि मैं यह कैसे देखने के लिए जाँचूंगा कि क्या इसे रद्द कर दिया गया है। ब्लॉक कोई तर्क नहीं लेता है, और उस समय ब्लॉक पर कब्जा किए जाने पर operation शून्य नहीं है। ब्लॉक आपरेशनों को रद्द करने का कोई रास्ता नहीं है?

Solutions Collecting From Web of "NSBlockOperation को कैसे रद्द करें"

रवींद्र। प्रिय भावी गोगलर्स: ब्लाक द्वारा प्रतिलिपि किए जाने पर निश्चित रूप से operation शून्य है, लेकिन इसे कॉपी करने की आवश्यकता नहीं है । इसे __block समान योग्य किया जा सकता है:

 //THIS MIGHT LEAK! See the update below. __block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ while( ! [operation isCancelled]){ //do something... } }]; 

अद्यतन करें:

आगे ध्यान पर, यह मेरे लिए होता है कि यह एआरसी के तहत एक बनाए चक्र बनाएगा। एआरसी में, मेरा मानना ​​है कि __block भंडारण रखा गया है। यदि हां, तो हम परेशानी में हैं, क्योंकि NSBlockOperation ब्लॉक में पारित करने के लिए मजबूत संदर्भ भी रखता है, जो अब ऑपरेशन के लिए एक मजबूत संदर्भ रखता है, जिसमें ब्लॉक में पारित करने का एक मजबूत संदर्भ है, जो …

यह थोड़ा कम सुरुचिपूर्ण है, लेकिन एक स्पष्ट कमजोर संदर्भ का उपयोग चक्र को तोड़ना चाहिए:

 NSBlockOperation *operation = [[NSBlockOperation alloc] init]; __weak NSBlockOperation *weakOperation = operation; [operation addExecutionBlock:^{ while( ! [weakOperation isCancelled]){ //do something... } }]; 

जिस किसी के पास और अधिक सुरुचिपूर्ण समाधान के लिए विचार हैं, कृपया टिप्पणी करें!

Jemmons उत्तर को मजबूत करने के लिए WWDC 2012 सत्र 211 – बिल्डिंग कंसूरेंट यूजर इंटरफेस (33 मिनट में)

 NSOperationQueue* myQueue = [[NSOperationQueue alloc] init]; NSBlockOperation* myOp = [[NSBlockOperation alloc] init]; // Make a weak reference to avoid a retain cycle __weak NSBlockOperation* myWeakOp = myOp; [myOp addExecutionBlock:^{ for (int i = 0; i < 10000; i++) { if ([myWeakOp isCancelled]) break; precessData(i); } }]; [myQueue addOperation:myOp]; 

स्विफ्ट 4 के साथ, आप addExecutionBlock(_:) साथ एक रद्द करने BlockOperation बना सकते हैं। addExecutionBlock(_:) में निम्नलिखित घोषणा है :

 func addExecutionBlock(_ block: @escaping () -> Void) 

निर्दिष्ट ब्लॉकों को प्राप्त करने के लिए प्राप्तकर्ता की सूची के ब्लॉक को जोड़ता है।


नीचे दिए गए उदाहरण से पता चला है कि addExecutionBlock(_:) कैसे कार्यान्वित करें:

 let blockOperation = BlockOperation() blockOperation.addExecutionBlock({ [unowned blockOperation] in for i in 0 ..< 10000 { if blockOperation.isCancelled { print("Cancelled") return // or break } print(i) } }) 

नोट करें कि, BlockOperation आवृत्ति और उसके निष्पादन ब्लॉक के बीच एक चक्र को रोकने के लिए, आपको निष्पादन ब्लॉक के अंदर blockOperation लिए एक weak या blockOperation संदर्भ के साथ एक कैप्चर सूची का उपयोग करना होगा।


निम्न खेल का मैदान कोड दिखाता है कि कैसे BlockOperation उपवर्ग उदाहरण और उसके निष्पादन ब्लॉक के बीच कोई चक्र नहीं है यह कैसे जांच करें:

 import Foundation import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true class TestBlockOperation: BlockOperation { deinit { print("No retain cycle") } } do { let queue = OperationQueue() let blockOperation = TestBlockOperation() blockOperation.addExecutionBlock({ [unowned blockOperation] in for i in 0 ..< 10000 { if blockOperation.isCancelled { print("Cancelled") return // or break } print(i) } }) queue.addOperation(blockOperation) Thread.sleep(forTimeInterval: 0.5) blockOperation.cancel() } 

यह प्रिंट करता है:

 1 2 3 ... Cancelled No retain cycle 

मुझे रद्द करने योग्य ब्लॉकों के पास होना था, जब मेरे स्क्रीन को स्क्रीन से स्क्रॉल किए जाने के बाद मेरे UICollectionViewController आसानी से रद्द कर सके। ब्लॉक नेटवर्क ऑप्स नहीं कर रहे हैं, वे छवि संचालन कर रहे हैं (आकार बदलने, फसल आदि) ब्लॉकों को स्वयं को यह देखने के लिए एक संदर्भ होना चाहिए कि क्या उनका ऑप रद्द कर दिया गया है, और अन्य जवाबों में से कोई भी (जब मैंने यह लिखा था) बशर्ते कि

मेरे लिए क्या काम है (स्विफ्ट 3) – ब्लॉकों को ब्लॉक BlockOperation लिए कमजोर रेफरी BlockOperation , फिर उन्हें BlockOperation ब्लॉक में BlockOperation हैं:

  public extension OperationQueue { func addCancellableBlock(_ block: @escaping (BlockOperation?)->Void) -> BlockOperation { let op = BlockOperation.init() weak var opWeak = op op.addExecutionBlock { block(opWeak) } self.addOperation(op) return op } } 

इसे मेरे UICollectionViewController में प्रयोग करना:

 var ops = [IndexPath:Weak<BlockOperation>]() func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { ... ops[indexPath] = Weak(value: DispatchQueues.concurrentQueue.addCancellableBlock({ (op) in cell.setup(obj: photoObj, cellsize: cellsize) })) } func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { if let weakOp = ops[indexPath], let op: BlockOperation = weakOp.value { NSLog("GCV: CANCELLING OP FOR INDEXPATH \(indexPath)") op.cancel() } } 

तस्वीर को पूरा करना:

  class Weak<T: AnyObject> { weak var value : T? init (value: T) { self.value = value } }