दिलचस्प पोस्ट
विजुअल स्टूडियो: कॉन्टेक्सस्विचडडलॉक एंड्रॉइड टाइमर एक टेक्स्टव्यू अपडेट करना (यूआई) क्या नियंत्रित करने का एक तरीका है कि कौन से अंतर्निहित रूपांतरण डिफ़ॉल्ट रूप से इस्तेमाल किया जाएगा? विंडोज 8 की स्वचालित रंग थीम का सक्रिय रंग प्राप्त करें पायथन में सूचियों की तुलना में ट्यूपल्स अधिक कुशल हैं? IEnumerable <T> के रूप में एक ही आइटम पास करना स्काला में ऑपरेटर की प्राथमिकता रेल 4 टर्बो-लिंक जेपीसी स्क्रिप्ट को काम से रोकता है जावा: नकारात्मक संख्या पर सही बदलाव जावा संकलित वर्गों में डॉलर के संकेत होते हैं रेजरपर अलग स्थान से यूनिट टेस्ट चलाता है क्यों "$ ()। तैयार (हैंडलर)" की सिफारिश नहीं की जाती है? एक्सएलएस (एक्सेल) फाइल से डेटा कैसे पढ़ा जाए Asp.Net MVC3: मान्य IServiceProvider को वैलिडेशन कॉन्टैक्ट में सेट करें ताकि वैलेटर्स सेवाओं को हल कर सकें सी ++ सॉकेट सर्वर – सीपीयू को पूर्ण करने में असमर्थ

उप-क्लासिंग एनएसओपरेशन को समवर्ती और रद्द करने योग्य

मैं NSOperation को समवर्ती कैसे NSOperation और रद्दीकरण का समर्थन करने के बारे में अच्छा दस्तावेज ढूंढने में असमर्थ हूं। मैंने एप्पल डॉक्स पढ़ा है, लेकिन मैं "आधिकारिक" उदाहरण ढूंढने में असमर्थ हूं।

यहां मेरा स्रोत कोड है:

 @synthesize isExecuting = _isExecuting; @synthesize isFinished = _isFinished; @synthesize isCancelled = _isCancelled; - (BOOL)isConcurrent { return YES; } - (void)start { /* WHY SHOULD I PUT THIS ? if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; return; } */ [self willChangeValueForKey:@"isExecuting"]; _isExecuting = YES; [self didChangeValueForKey:@"isExecuting"]; if (_isCancelled == YES) { NSLog(@"** OPERATION CANCELED **"); } else { NSLog(@"Operation started."); sleep(1); [self finish]; } } - (void)finish { NSLog(@"operationfinished."); [self willChangeValueForKey:@"isExecuting"]; [self willChangeValueForKey:@"isFinished"]; _isExecuting = NO; _isFinished = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; if (_isCancelled == YES) { NSLog(@"** OPERATION CANCELED **"); } } 

उदाहरण के लिए मैंने पाया, मुझे समझ में नहीं आता है कि क्यों करें selectorOnMainThread: उपयोग किया जाता है यह मेरे ऑपरेशन को एक साथ चलने से रोक देगा।

इसके अलावा, जब मैं उस रेखा पर टिप्पणी करता हूं, तो मैं अपने आपरेशनों को एक साथ चलाता हूं। हालांकि, cancelAllOperations किया गया ध्वज संशोधित नहीं किया गया है, भले ही मैंने cancelAllOperations को बुलाया है।

वेब के समाधान से एकत्रित समाधान "उप-क्लासिंग एनएसओपरेशन को समवर्ती और रद्द करने योग्य"

ठीक है, जैसे कि मैं इसे समझता हूं, आपके पास दो प्रश्न हैं:

  1. क्या आपको प्रदर्शन करने की आवश्यकता performSelectorOnMainThread: सेगमेंट जो आपके कोड में टिप्पणियों में प्रकट होता है? यह कोड क्या करता है?

  2. जब आप cancelAllOperations कर देते हैं, तो cancelAllOperations पर सभी cancelAllOperations इस ऑपरेशन में शामिल होने पर _isCancelled ध्वज को संशोधित नहीं किया जाता है?

आइए इनके साथ व्यवहार करें। मैं यह मानने जा रहा हूं कि स्पष्टीकरण में आसानी के लिए, MyOperation आपके उपवर्ग को MyOperation कहा जाता है मैं आपको समझाता हूं कि आप क्या गलतफहमी कर रहे हैं और फिर एक सही उदाहरण दें।

1. समवर्ती NSOperations चल रहा है

अधिकांश समय, आप NSOperation s को NSOperation साथ उपयोग करेंगे, और आपके कोड से, ऐसा लगता है कि आप क्या कर रहे हैं। उस स्थिति में, आपका MyOperation हमेशा पृष्ठभूमि थ्रेड पर चलाया जाएगा, भले ही -(BOOL)isConcurrent पद्धति का तरीका रिटर्न, क्योंकि -(BOOL)isConcurrent स्पष्ट रूप से पृष्ठभूमि में संचालन चलाने के लिए डिज़ाइन किया गया है।

जैसे, आपको आमतौर पर -[NSOperation start] विधि को ओवरराइड करने की आवश्यकता नहीं है, क्योंकि डिफ़ॉल्ट रूप से यह केवल -main विधि का आह्वान करता है यही विधि आपको ओवरराइड करना चाहिए डिफ़ॉल्ट isExecuting विधि पहले से ही संभालती है सेटिंग को isExecuting और उचित समय पर आपके लिए isFinished

इसलिए यदि आप पृष्ठभूमि में चलाने के लिए एक NSOperation चाहते हैं, तो बस -main विधि को ओवरराइड करें और इसे एक NSOperationQueue

performSelectorOnMainThread: अपने कोड में MyOperation हर उदाहरण हमेशा मुख्य धागा पर अपने कार्य को करने के लिए कारण होगा। चूंकि केवल एक टुकड़ा कोड एक धागे पर एक समय में चल सकता है, इसका मतलब यह है कि कोई अन्य MyOperation चल रहा हो सकता है। NSOperation और NSOperationQueue का पूरा उद्देश्य पृष्ठभूमि में कुछ करना है।

जब आप मुख्य थ्रेड पर चीजों को मजबूर करना चाहते हैं, तो आप उस समय जब उपयोगकर्ता इंटरफ़ेस को अपडेट कर रहे हैं यदि आप MyOperation समाप्त होने पर UI को अपडेट करने की आवश्यकता होती है, तो जब आप का प्रयोग करें MyOperation उपयोग करना चाहिए:। मैं नीचे दिखाएगा कि मेरे उदाहरण में यह कैसे करना है।

2. एक एनएसओपरेशन रद्द करना

-[NSOperationQueue cancelAllOperations] कॉल करता है -[NSOperation cancel] विधि, जिसके कारण बाद के कॉल का कारण बनता है -[NSOperation cancel] YES वापस करने के लिए हालांकि , आपने इस अप्रभावी बनाने के लिए दो चीजें कर ली हैं।

  1. आप @synthesize isCancelled -isCancelled का प्रयोग कर रहे हैं, -isCancelled की @synthesize isCancelled से -isCancelled की -isCancelled विधि को ओवरराइड करने के लिए -isCancelled है। ऐसा करने का कोई कारण नहीं है NSOperation पहले से ही लागू -isCancelled है – एक पूरी तरह स्वीकार्य तरीके से -isCancelled गया।

  2. आप यह निर्धारित करने के लिए कि क्या आपरेशन रद्द कर दिया गया है, अपने स्वयं के _isCancelled आवृत्ति चर की जांच कर रहे हैं। NSOperation गारंटी देता है कि [self isCancelled] को रद्द कर दिया गया है [self isCancelled] यदि रद्द कर दिया गया है तो YES वापस आ जाएगी। यह गारंटी नहीं देता है कि आपकी कस्टम सेटर विधि को बुलाया जाएगा, और न ही आपकी खुद की आवृत्ति चर अद्यतित है। आप की जांच होनी चाहिए [self isCancelled]

आपको क्या करना चाहिए

हैडर:

 // MyOperation.h @interface MyOperation : NSOperation { } @end 

और कार्यान्वयन:

 // MyOperation.m @implementation MyOperation - (void)main { if ([self isCancelled]) { NSLog(@"** operation cancelled **"); } // Do some work here NSLog(@"Working... working....") if ([self isCancelled]) { NSLog(@"** operation cancelled **"); } // Do any clean-up work here... // If you need to update some UI when the operation is complete, do this: [self performSelectorOnMainThread:@selector(updateButton) withObject:nil waitUntilDone:NO]; NSLog(@"Operation finished"); } - (void)updateButton { // Update the button here } @end 

ध्यान दें कि आपको कुछ भी करने की ज़रूरत नहीं है, isExecuting , isExecuting , या isFinished । उन सभी को आपके लिए स्वचालित रूप से संभाला जाता है बस-मुख्य विधि को ओवरराइड करें इट्स दैट ईजी।

(एक नोट: तकनीकी रूप से, यह एक "समवर्ती" -[MyOperation isConcurrent] नहीं है, इस अर्थ में कि -[MyOperation isConcurrent] NO ऊपर लौटाएगा जैसा कि ऊपर उल्लिखित NO होगा। हालांकि, यह पृष्ठभूमि के धागे पर चलने वाला isConcurrent विधि को वास्तव में नाम दिया जाना चाहिए -willCreateOwnThread , क्योंकि यह विधि के इरादे का अधिक सटीक वर्णन है।)

मुझे पता है यह एक पुराना सवाल है, लेकिन मैं हाल ही में इस बारे में जांच कर रहा हूं और उसी उदाहरण का सामना कर रहा हूं और मुझे एक ही संदेह था।

यदि आपके सभी काम मुख्य विधि के अंदर समन्वयित हो सकते हैं, तो आपको एक समवर्ती संचालन की आवश्यकता नहीं है, न ही प्रारंभिक ओवरराइड करना है, बस अपना काम करें और जब से किया जाए तो मुख्य से लौटें।

हालांकि, यदि आपका वर्कलोड प्रकृति द्वारा एसिंक्रोनस है – यानी एनएसआरआर कनेक्शन लोड हो रहा है, तो आपको उपवर्ग शुरू करना होगा। जब आपकी प्रारंभिक विधि वापस आती है, तो ऑपरेशन अभी समाप्त नहीं हुआ है यह केवल NSOperationQueue द्वारा समाप्त होने पर विचार किया जाएगा जब आप मैन्युअल रूप से केवीओ नोटिफिकेशन को मैन्युअल रूप से भेजते हैं और समाप्त हो रहे हैं (उदाहरण के लिए, एक बार async URL लोड हो रहा है या विफल रहता है)।

अंत में, कोई मुख्य थ्रेड से शुरू प्रेषण करना चाहता हो सकता है जब आप एसिंक वर्कलोड को प्रारंभ करना चाहते हैं, मुख्य थ्रेड पर रन-लूप सुनना आवश्यक है। जैसे ही काम असिंक्रोनस है, यह आपकी संगामिति को सीमित नहीं करेगा, लेकिन कार्यकर्ता थ्रेड में काम शुरू करने पर उचित रनलोप तैयार नहीं हो सकता है।

@JJHomer का उत्कृष्ट जवाब एक अद्यतन के योग्य है

समवर्ती संचालन main बजाय start विधि को ओवरराइड करना चाहिए।

जैसा कि एप्पल प्रलेखन में कहा गया है:

यदि आप एक समवर्ती कार्रवाई कर रहे हैं, तो आपको निम्न विधियों और गुणों को कम से कम ओवरराइड करना होगा:

  • start
  • asynchronous
  • executing
  • finished

एक उचित कार्यान्वयन को cancel भी आवश्यक है। एक उपवर्ग धागा सुरक्षित बनाना और आवश्यक शब्दों को प्राप्त करना भी बहुत मुश्किल है।

इस प्रकार, मैंने स्विफ्ट इन कोड रिव्यू में लागू किए गए प्रस्ताव के रूप में एक पूर्ण और काम कर उप-वर्ग रखा है । टिप्पणियाँ और सुझाव का स्वागत है

यह क्लास आसानी से आपके कस्टम ऑपरेशन क्लास के लिए बेस क्लास के रूप में इस्तेमाल किया जा सकता है।

ASIHTTPRequest पर एक नज़र डालें यह उप-वर्ग के रूप में NSOperation शीर्ष पर बनाया गया एक HTTP आवरण वर्ग है और इन्हें लागू करने के लिए लगता है ध्यान दें कि 2011 के मध्य के रूप में, डेवलपर नई परियोजनाओं के लिए एएसआई का उपयोग नहीं करने की सिफारिश करता है।

NSOperation subclass के भीतर " रद्द " संपत्ति (या " _cancelled " IVAR को परिभाषित करने के बारे में परिभाषित करने के बारे में, आमतौर पर यह आवश्यक नहीं है। सिर्फ इसलिए कि जब उपयोगकर्ता रद्द करना शुरू करता है, तो कस्टम कोड को हमेशा केवीओ पर्यवेक्षक को सूचित करना चाहिए कि आपका ऑपरेशन अब अपने कार्य के साथ समाप्त हो गया है दूसरे शब्दों में, isCancelled => समाप्त हो गया है।

विशेष रूप से, जब एनएसओपरेशन ऑब्जेक्ट अन्य ऑपरेशन ऑब्जेक्ट्स के पूरा होने पर निर्भर होता है, तो यह उन ऑब्जेक्ट्स के लिए फाइन की गई कुंजी पथ पर नज़र रखता है। एक पूर्ण अधिसूचना उत्पन्न करने में नाकाम रहने ( रद्दीकरण के मामले में ) इसलिए आपके आवेदन में अन्य कार्यों के निष्पादन को रोका जा सकता है।


बीटीडब्लू, बी.जे. होमर का जवाब: "आईकंक्रार्चंट मेथड को वास्तव में नाम दिया जाना चाहिए- विलल कटलेट थ्रेड" बहुत मायने रखता है !

क्योंकि अगर आप प्रारंभ-विधि को ओवरराइड नहीं करते हैं, तो बस मैन्युअल रूप से एनएसओपरेशन-ऑब्जेक्ट की डिफ़ॉल्ट-प्रारंभ-विधि को कॉल करते हैं, कॉलिंग-थ्रेड ही डिफ़ॉल्ट रूप से, तुल्यकालिक है; इसलिए, एनएसओपरेशन-ऑब्जेक्ट केवल एक गैर-समवर्ती संचालन है।

हालांकि, यदि आप प्रारंभ-विधि को ओवरराइड करते हैं, तो प्रारंभ-विधि कार्यान्वयन के अंदर, कस्टम-कोड को एक अलग धागा उत्पन्न करना चाहिए … आदि, फिर आप सफलतापूर्वक "कॉलिंग-थ्रेड डिफ़ॉल्ट सिंक्रोनस" का प्रतिबंध तोड़ सकते हैं, इसलिए NSOperation-Object बनने से समवर्ती संचालन, यह अतुल्यकालिक बाद में चला सकता है

इस ब्लॉग पोस्ट:

http://www.dribin.org/dave/blog/archives/2009/09/13/snowy_concurrent_operations/

बताते हैं कि आपको क्यों आवश्यकता हो सकती है:

 if (![NSThread isMainThread]) { [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; return; } 

अपनी start विधि में