2013-04-17 10 views
10

हर बार जब मैं इस तरह की एक ब्लॉक के अंदर एक वैश्विक वर या संपत्ति का उपयोग करने के "इस ब्लॉक में दृढ़ता से कब्जा स्वयं एक बनाए रखने के चक्र के लिए नेतृत्व की संभावना है" इस तरहबचना संदेश

BOOL *iis = isItSaving; 
id myself = self; 

self.save = ^(){ 
    if (iis == NO) { 
     [myself saveMyFile]; 
    } 
}; 

या Xcode शिकायत "दृढ़ता से इस ब्लॉक में स्वयं पर कब्जा करने के लिए एक चक्र को बनाए रखने के लिए नेतृत्व की संभावना है ...

यह भी BOOL चर के बारे में शिकायत?

ब्लॉक से पहले सब कुछ पुनः लोड करना एक लंगड़ा समाधान प्रतीत होता है।

क्या यह सही तरीके से है? क्या कोई सुरुचिपूर्ण तरीका है?

यह सामान बदसूरत है। मैं एआरसी का उपयोग कर रहा हूँ।

उत्तर

20

समस्या तब होती है जब ब्लॉक के भीतर self का संदर्भ स्पष्ट रूप से या स्पष्ट रूप से किया जाता है। वैश्विक चर का उपयोग करते समय उत्सर्जित कोई चेतावनी नहीं है।

आपके मामले में आप शायद (बूलियन) ivar तक पहुंच सकते हैं। Ivar तक पहुंचने से self का उपयोग किया जाता है, यही कारण है कि संकलक आपको एक सतत चक्र के बारे में चेतावनी दे रहा है (सही ढंग से)।

चक्र को बनाए रखने के ठीक करने के लिए आम तरीका है:

typeof(self) __weak weakSelf = self; 

self.save = ^() { 
    typeof(weakSelf) __strong strongSelf = weakSelf; 
    if (strongSelf != nil && ! strongSelf->isItSaving) { 
     [strongSelf saveMyFile]; 
    } 
}; 

... और, हाँ, कि ब्लॉक के एक बदसूरत हिस्सा का एक सा है।

+1

आदमी, यह नरक के रूप में बदसूरत है। सबकुछ फिर से शुरू करने के लिए ... धन्यवाद। – SpaceDog

+0

@ मार्क आर्मरी हां, क्लैंग अधिक से अधिक मुद्दों को पकड़ता है। और यह सही है, संलग्न वस्तु का जीवनकाल कम से कम तब तक बढ़ाया जाना चाहिए जब तक कि ब्लॉक खत्म न हो जाए। संपादन ... –

+1

@ निकोलईरुहे * "संलग्न वस्तु का जीवनकाल कम से कम तब तक बढ़ाया जाना चाहिए जब तक कि ब्लॉक खत्म नहीं हो जाता" * - अच्छा, मैंने पहली बार किसी भी कारण से नोटिस नहीं किया कि ब्लॉक के भीतर 'स्वयं' का मजबूत संदर्भ क्यों बना रहा है '__unsafe_unretained' का उपयोग करने के लिए बेहतर होगा, लेकिन अकेले वाक्यांश यह अविश्वसनीय रूप से स्पष्ट बनाता है। यदि आप चाहें तो अपने उत्तर में दो दृष्टिकोणों की तुलना करने के लायक भी हो सकते हैं। –

4

जब गुण

BOOL *iis = isItSaving; 
id myself = self; 

घोषित करने का प्रयोग करें __unsafe_unretained typeof(self) weakSelf = self;

+0

मुझे लगता है कि आप एआरसी के साथ __unsafe_unretained का उपयोग नहीं कर सकते – SpaceDog

0

@ NikolaiRuhe की प्रतिक्रिया के अलावा, अपने उदाहरण में strong संदर्भ का तात्पर्य है, तो __weak स्वयं का उपयोग चक्र को बनाए रखने को रोकने के लिए। तो आपको आश्चर्य हो सकता है कि आपको ब्लॉक के भीतर कमजोर आत्म के संदर्भ में __strong घोषित करने की आवश्यकता क्यों है, और यह सुनिश्चित करना है कि यह ब्लॉक के जीवन के दौरान जारी नहीं किया जाता है, अन्यथा weakSelf->isItSavingself जारी किए जाने पर तोड़ देगा।

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