9

में ivar ब्लॉक में स्वयं संदर्भ चक्र __ ब्लॉक करें मुझे ब्लॉक ivar में एक स्पष्ट संदर्भ चक्र के साथ कुछ कोड मिला है। निम्नलिखित कोड एक संदर्भ चक्र का कारण बनता है और dealloc कभी नहीं कहा जाता है:एआरसी

__block MyViewController *blockSelf = self; 

loggedInCallback = ^(BOOL success, NSError *error){ 
    if (success) 
    { 
     double delayInSeconds = 1.0; 
     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
     dispatch_after(popTime, dispatch_get_main_queue(), ^(void) 
     { 
      [blockSelf.delegate loginDidFinish]; 
     });    
    } 
}; 

हालांकि, अगर मैं एक __block चर बनाने पर कब्जा करने के लिए ब्लॉक की गुंजाइश के लिए मेरे प्रतिनिधि के लिए एक संदर्भ पकड़ करने के लिए, संदर्भ चक्र चला जाता है:

__block id <MyViewControllerDelegate> blockDelegate = self.delegate; 

loggedInCallback = ^(BOOL success, NSError *error){ 
    if (success) 
    { 
     double delayInSeconds = 1.0; 
     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
     dispatch_after(popTime, dispatch_get_main_queue(), ^(void) 
     { 
      [blockDelegate loginDidFinish]; 
     });    
    } 
}; 

बस यह समझना है कि यहां क्या हो रहा है।

उत्तर

16

मैं आपको एआरसी का उपयोग करके मानने जा रहा हूं। एआरसी से पहले, आपका पहला उदाहरण ठीक काम करेगा। एआरसी के साथ __block के अर्थशास्त्र बदल गए हैं। __block घोषणाओं को कमजोर रूप से बजाए, दृढ़ता से कब्जा कर लिया गया है। अपने पहले नमूने में के साथ __block को बदलें और सभी को अपेक्षित कार्य करना चाहिए।

दूसरे उदाहरण के काम के लिए, आप प्रतिनिधि के लिए एक मजबूत संदर्भ बना रहे हैं, लेकिन आपके पास आपके ऑब्जेक्ट का संदर्भ नहीं है। इस प्रकार कोई चक्र नहीं है और हर कोई खुश है।

मैं एआरसी के साथ किए गए बदलावों पर माइक ऐश के लेख को पढ़ने की सलाह देते हैं, विशेष रूप से ब्लॉक पर कब्जा के आसपास है और __weakhttp://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

+0

बिल्कुल सही है, धन्यवाद! मैंने अपने प्रश्न का शीर्षक अधिक वर्णनात्मक होने के लिए अद्यतन किया है। –

+1

मैं आईओएस 4.3 को लक्षित कर रहा हूं, इसलिए मुझे इसके बजाय '' __unsafe_unretained'' का उपयोग करना पड़ा, लेकिन यह काम करता है, धन्यवाद! –