दिलचस्प पोस्ट
सी – एक फंक्शन तर्क के रूप में एक 2d सरणी गुजर रहा है? दृश्य स्टूडियो में डिफ़ॉल्ट रूप से प्रोजेक्ट से सुरक्षित चेतावनियां निकालें (_CRT_SECURE_NO_WARNINGS) पोस्ट के माध्यम से एक ही नाम के साथ कई इनपुट पीएचपी में उपयोगकर्ता नाम और पासवर्ड के साथ नेटवर्क ड्राइव से कनेक्ट करें जब एक टुकड़ा को बदल दिया जाता है और पीछे की ढेर (या हटाया गया) में रखता है तो क्या वह स्मृति में रहती है? CreateWindowExW का उपयोग करते समय हीप भ्रष्टाचार JTable में स्तंभों के आधार पर पंक्तियाँ छंटनी कक्षा के भीतर पायथन कॉल फंक्शन कैसे एक डेटाफ्रेम पिवट करने के लिए क्या नियमित अभिव्यक्ति में एक काउंटर वेरिएबल की तरह कुछ है? jquery का उपयोग कर जांच / अनचेक चेकबॉक्स? जावा में थ्रेड सुरक्षित मल्टीटाउन एप में म्यूपीडीएफ रीडर को एकीकृत करें Jquery द्वारा बंद खिड़कियों की घटना का पता लगाएं पायथन के eval () क्या करता है?

हमेशा एआरसी में ब्लॉक में आत्म का कमजोर संदर्भ पास करें?

मैं उद्देश्य-सी में ब्लॉक उपयोग के बारे में थोड़ा भ्रमित हूँ मैं वर्तमान में एआरसी का उपयोग करता हूं और मेरे पास मेरे ऐप में बहुत अधिक ब्लॉकों हैं, वर्तमान में हमेशा अपने कमजोर संदर्भ के बजाय self बात करते हुए। हो सकता है कि इन ब्लॉकों का कारण self बरकरार रखे और इसे डिलोक किया जा रहा है? सवाल यह है, क्या मुझे हमेशा एक ब्लॉक में self का weak संदर्भ इस्तेमाल करना चाहिए?

 -(void)handleNewerData:(NSArray *)arr { ProcessOperation *operation = [[ProcessOperation alloc] initWithDataToProcess:arr completion:^(NSMutableArray *rows) { dispatch_async(dispatch_get_main_queue(), ^{ [self updateFeed:arr rows:rows]; }); }]; [dataProcessQueue addOperation:operation]; } 

ProcessOperation.h

 @interface ProcessOperation : NSOperation { NSMutableArray *dataArr; NSMutableArray *rowHeightsArr; void (^callback)(NSMutableArray *rows); } 

ProcessOperation.m

 -(id)initWithDataToProcess:(NSArray *)data completion:(void (^)(NSMutableArray *rows))cb{ if(self =[super init]){ dataArr = [NSMutableArray arrayWithArray:data]; rowHeightsArr = [NSMutableArray new]; callback = cb; } return self; } - (void)main { @autoreleasepool { ... callback(rowHeightsArr); } } 

वेब के समाधान से एकत्रित समाधान "हमेशा एआरसी में ब्लॉक में आत्म का कमजोर संदर्भ पास करें?"

यह चर्चा के strong या weak हिस्से पर ध्यान केंद्रित नहीं करने में मदद करता है। इसके बजाय चक्र भाग पर ध्यान केंद्रित करें।

एक बनाए चक्र एक ऐसा लूप होता है, जब वस्तु A को ऑब्जेक्ट बी को बरकरार रखता है, और ऑब्जेक्ट बी ऑब्जेक्ट ए को बरकरार रखता है। उस स्थिति में, यदि कोई ऑब्जेक्ट रिलीज़ हो जाती है:

  • ऑब्जेक्ट A को इसलिए वितरित नहीं किया जाएगा क्योंकि ऑब्जेक्ट बी इसके संदर्भ में रखता है।
  • लेकिन ऑब्जेक्ट बी को तब तक वितरित नहीं किया जाएगा, जब तक ऑब्जेक्ट ए का कोई संदर्भ नहीं होता।
  • लेकिन ऑब्जेक्ट A को कभी भी वितरित नहीं किया जाएगा क्योंकि ऑब्जेक्ट बी इसके संदर्भ में है।
  • एड इन्फिटम

इस प्रकार, उन दो ऑब्जेक्ट्स प्रोग्राम के जीवन के लिए स्मृति में चारों ओर लटकाए होंगे, भले ही वे सब कुछ ठीक से काम कर रहे हों, तो उन्हें हटाना चाहिए।

इसलिए, हम जो चिंतित हैं, वे चक्र बनाए रखते हैं, और इन चक्रों को बनाने वाले और खुद के ब्लॉकों के बारे में कुछ नहीं है यह कोई समस्या नहीं है, उदाहरण के लिए:

 [myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ [self doSomethingWithObject:obj]; }]; 

ब्लॉक self बरकरार रखता है, लेकिन self ब्लॉक को नहीं रखता है। यदि एक या कोई अन्य जारी किया जाता है, तो कोई चक्र नहीं बनाया जाता है और सबकुछ को उतना ही वितरित किया जाता है जितना चाहिए।

जहां आप मुसीबत में आते हैं, वह ऐसा कुछ है:

 //In the interface: @property (strong) void(^myBlock)(id obj, NSUInteger idx, BOOL *stop); //In the implementation: [self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) { [self doSomethingWithObj:obj]; }]; 

अब, आपके ऑब्जेक्ट ( self ) का ब्लॉक के लिए स्पष्ट स्पष्ट संदर्भ है। और ब्लॉक में self का एक गहरा असर होता है यह एक चक्र है, और अब न ही ऑब्जेक्ट को ठीक तरह से वितरित किया जाएगा

क्योंकि, इस तरह की स्थिति में, परिभाषा के द्वारा self को ब्लॉक के लिए पहले से ही एक strong संदर्भ मिला है, ब्लॉक के उपयोग के लिए self को स्पष्ट रूप से कमजोर संदर्भ बनाने के द्वारा इसे हल करना सबसे आसान होता है:

 __weak MyObject *weakSelf = self; [self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) { [weakSelf doSomethingWithObj:obj]; }]; 

लेकिन self कॉल करने वाले ब्लॉकों से निपटने पर यह आपके द्वारा अनुवर्ती डिफ़ॉल्ट पद्धति नहीं होनी चाहिए ! इसका उपयोग केवल तोड़ने के लिए किया जाना चाहिए जो अन्यथा स्वयं और ब्लॉक के बीच एक चक्र को बनाए रखेगा। यदि आप हर जगह इस पद्धति को अपनाना चाहते थे, तो आप किसी ब्लॉक को पास करने के जोखिम को चला सकते थे जो self को हटाए जाने के बाद निष्पादित हो गया था।

 //SUSPICIOUS EXAMPLE: __weak MyObject *weakSelf = self; [[SomeOtherObject alloc] initWithCompletion:^{ //By the time this gets called, "weakSelf" might be nil because it's not retained! [weakSelf doSomething]; }]; 

आपको हमेशा एक कमजोर संदर्भ का उपयोग करने की आवश्यकता नहीं है यदि आपके ब्लॉक को बरकरार रखा नहीं गया है, लेकिन निष्पादित किया जाता है और फिर त्याग दिया जाता है, तो आप आत्म दृढ़ता से कब्जा कर सकते हैं, क्योंकि यह एक बनाए चक्र बनाएगा नहीं। कुछ मामलों में, आप ब्लॉक को पूरा करने तक ब्लॉक भी स्वयं को पकड़ने के लिए चाहते हैं, इसलिए यह समय से पहले ही आवंटित नहीं करता है। अगर, हालांकि, आप ब्लॉक को दृढ़ता से कैप्चर करते हैं, और स्वयं को कैप्चर करते समय, यह एक बनाए चक्र बनाएगा।

मैं पूरी तरह से @jemmons से सहमत हूं

"लेकिन यह आपके द्वारा उल्लिखित ब्लॉकों से निपटने वाला डिफ़ॉल्ट स्वरूप नहीं होना चाहिए! स्वयं को कॉल करने वाले ब्लॉकों के साथ व्यवहार करने के लिए इसका इस्तेमाल किया जाना चाहिए अन्यथा स्वयं और ब्लॉक के बीच एक चक्र बनाए रखने के लिए इसका इस्तेमाल किया जाना चाहिए। अगर आप इस पद्धति को हर जगह अपनाते हैं, घ एक ब्लॉक को पारित करने का जोखिम चलाता है जिसे स्वयं को हटाए जाने के बाद निष्पादित किया गया था। "

 //SUSPICIOUS EXAMPLE: __weak MyObject *weakSelf = self; [[SomeOtherObject alloc] initWithCompletion:^{ //By the time this gets called, "weakSelf" might be nil because it's not retained! [weakSelf doSomething]; }]; 

इस समस्या से अधिक आने के लिए, कमजोरों पर एक मजबूत संदर्भ को परिभाषित कर सकते हैं, ब्लॉक के अंदर स्वयं।

 __weak MyObject *weakSelf = self; [[SomeOtherObject alloc] initWithCompletion:^{ MyObject *strongSelf = weakSelf; [strongSelf doSomething]; }]; 

जैसा कि लियो बताता है, आपके द्वारा आपके प्रश्न में जो कोड जोड़ा गया है, वह एक मजबूत संदर्भ चक्र (उर्फ, चक्र बनाए रखने) का सुझाव नहीं देगा। एक ऑपरेशन संबंधी समस्या जो एक मजबूत संदर्भ चक्र का कारण बन सकती है, यदि ऑपरेशन जारी नहीं हो रहा है जबकि आपका कोड स्निपेट आपको सूचित करता है कि आपने अपने ऑपरेशन को समवर्ती बनाने के लिए परिभाषित नहीं किया है, लेकिन यदि आपके पास है, तो यह रिलीज़ नहीं होगा, यदि आपने कभी पोस्ट नहीं किया है, या यदि आपके पास परिपत्र निर्भरता है, या ऐसा कुछ है और यदि ऑपरेशन जारी नहीं होता है, तो दृश्य नियंत्रक को या तो रिलीज़ नहीं किया जाएगा। मैं आपके ऑपरेशन की dealloc पद्धति में एक ब्रेकपॉइंट या NSLog जोड़ने का सुझाव देता हूं और पुष्टि करता हूं कि उसे कॉल करना पड़ रहा है।

तुमने कहा था:

मैं चक्र को बनाए रखने की धारणा समझता हूं, लेकिन मुझे पूरा यकीन नहीं है कि ब्लॉकों में क्या होता है, जिससे मुझे थोड़ा सा भ्रमित हो

ब्लॉक के साथ होने वाली बनाए रखने वाले चक्र (मजबूत संदर्भ चक्र) समस्याएं उन चक्रों के समान हैं जो आप परिचित हैं। ब्लॉक ब्लॉक के भीतर दिखाई देने वाले किसी भी ऑब्जेक्ट के लिए एक ब्लॉक मजबूत संदर्भ बनाएगा, और यह उन मजबूत संदर्भों को तब तक रिलीज नहीं करेगा जब तक ब्लॉक स्वयं जारी नहीं किया जाता है। इस प्रकार, अगर ब्लॉक self संदर्भ देता है, या self एक उदाहरण चर का भी संदर्भ देता है, जो self मजबूत संदर्भ बनाए रखेगा, जो तब तक हल नहीं हो रहा है जब तक ब्लॉक जारी नहीं किया जाता है (या इस मामले में, जब तक कि NSOperation subclass जारी नहीं किया जाता है

अधिक जानकारी के लिए, उद्देश्य-सी के साथ प्रोग्रामिंग के स्वयं अनुभाग को कैप्चर करते समय सख्त संदर्भ चक्र देखें : ब्लॉक दस्तावेज़ के साथ कार्य करना

यदि आपका दृश्य नियंत्रक अब भी जारी नहीं हो रहा है, तो आपको यह पता होना चाहिए कि अनसुलझे मजबूत संदर्भ कहां स्थित हैं (मान लें कि आपने पुष्टि की है कि NSOperation को रद्द कर दिया जा रहा है)। एक सामान्य उदाहरण एक पुनरावृत्ति NSTimer का उपयोग होता है या कुछ कस्टम delegate या गलत ऑब्जेक्ट जो गहराई से strong संदर्भ बनाए रखते हैं आप उपकरण को नीचे ट्रैक करने के लिए अक्सर उपकरण का उपयोग कर सकते हैं जहां ऑब्जेक्ट अपने मजबूत संदर्भों को प्राप्त कर रहे हैं, जैसे:

Xcode 6 में रिकॉर्ड संदर्भ मायने रखता है

या एक्सकोड 5 में:

Xcode 5 में रिकॉर्ड संदर्भ मायने रखता है

कुछ स्पष्टीकरण को बनाए रखने के चक्र के बारे में एक शर्त को अनदेखा करना [यदि समूह का एक समूह मजबूत संबंधों के एक चक्र से जुड़ा होता है, तो वे एक दूसरे को जीवित रखते हैं भले ही समूह के बाहर कोई मजबूत संदर्भ न हो।] अधिक जानकारी के लिए, दस्तावेज़ पढ़ें

इस तरह आप ब्लॉक के अंदर स्वयं का उपयोग कर सकते हैं:

// ब्लॉक के कॉलिंग

  NSString *returnedText= checkIfOutsideMethodIsCalled(self); 

 NSString* (^checkIfOutsideMethodIsCalled)(*)=^NSString*(id obj) { [obj MethodNameYouWantToCall]; // this is how it will call the object return @"Called"; }; 

यह एक उदाहरण के साथ समझाने के लिए सबसे अच्छा हो सकता है निम्नलिखित को देखते हुए

 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ [self doSomethingWithObject:obj]; }]; 

यदि 'स्व' एक दृश्य नियंत्रक था और इसे एक मूल दृश्य नियंत्रक द्वारा खारिज कर दिया गया था तो मैं चाहता हूं कि दृश्य नियंत्रक को स्मृति से हटाया जाना चाहिए हालांकि, उपरोक्त विधि स्वयं के लिए एक मजबूत संदर्भ रखेगी और इस प्रकार दृश्य नियंत्रक को स्मृति में तब तक रहेगा जब तक कि गणना ऑब्जेक्ट विधि पूरी तरह से निष्पादित नहीं हो जाती।

अगर हम खुद के लिए एक कमजोर संदर्भ में पारित हो जाते हैं, तो दृश्य नियंत्रक को खारिज कर दिया गया था, जब वह शून्य हो जाएगा।

 __weak CustomViewController *weakSelf = self; [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ [weakSelf doSomethingWithObject:obj]; }];