9

यह एक वस्तु आवंटित करने के लिए, यह एक पूरा होने हैंडलर के साथ कुछ सामान करते हैं और हैंडलर में इसे जारी मेरे कोड में एक आम पैटर्न है:मैं एआरसी के तहत ब्लॉक समापन हैंडलर के साथ ऑब्जेक्ट कैसे जारी करूं?

LongOperation *foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [foo autorelease]; 
}]; 

यह काफी अच्छी तरह से काम करता है, लेकिन जब मैं कोड रूपांतरित करने का प्रयास एआरसी के लिए, एक्सकोड सही मायने में शिकायत करता है कि यह ब्लॉक से autorelease को आसानी से नहीं छोड़ सकता है, क्योंकि इससे foo ऑब्जेक्ट को दायरे को छोड़ने के बाद हटा दिया जाएगा।

तो एआरसी के तहत इस प्रकार के पैटर्न को लिखने का एक अच्छा तरीका क्या है? मैं foo के लिए एक उदाहरण चर परिचय सकता है:

[self setFoo:[[LongOperation alloc] init]]; 
[foo runWithCompletion:^{ 
    // run some code and then: 
    [self setFoo:nil]; 
}]; 

... लेकिन कोड अब और फिर से प्रवेशी नहीं किया जाएगा।

उत्तर

4

ज्यादातर मामलों में, यह काम करना चाहिए (यानी, यदि कुछ भी foo के अंदर स्वयं संदर्भित करता है, तो foo दूर जाने से पहले उस कोड को संतुष्ट करने के लिए पर्याप्त समय तक टिकेगा)। अगर वहाँ कमजोर संदर्भ और ऐसी है कि foo लगता है कि इसे दूर जाना चाहिए, लेकिन नहीं जब तक के बाद हैंडलर चलाता है, आप की तरह कुछ कर सकते हैं चाहिए के साथ मुद्दे हैं:

__block LongOperation* foo = [[LongOperation alloc] init]; 
[foo runWithCompletion:^{ 
    // do some things 
    foo = nil; 
}]; 

नोट इस इस पद्धति के विपरीत की तरह है जो प्रबंधित स्मृति नियमों के तहत ऑब्जेक्ट/नहीं/कब्जा करने का कारण बनता है।

+0

यह सवाल का जवाब नहीं देता है कि जब फू युक्त संदर्भ में लंबे समय तक संदर्भित किया जाता है तो क्या करना है। इस समाधान के साथ, स्टैक फ्रेम जो कॉल करता है [foo runWithCompletion:] को तब तक अवरुद्ध करना चाहिए जब तक रन पूर्ण हो या स्टैक स्मैशर को जोखिम न दे। –

संबंधित मुद्दे