__Weak और __block संदर्भ में क्या अंतर है?


80

मैं Xcode का प्रलेखन पढ़ रहा हूँ, और यहाँ कुछ है जो मुझे पहेलियाँ:

__block typeof(self) tmpSelf = self;
[self methodThatTakesABlock:^ {
    [tmpSelf doSomething];
}];

निम्नलिखित को प्रलेखन से कॉपी किया गया है:

ब्लॉक इसे कैप्चर करने वाले चर के लिए एक मजबूत संदर्भ बनाता है। यदि आप selfकिसी ब्लॉक के भीतर उपयोग करते हैं, तो ब्लॉक एक मजबूत संदर्भ बनाता है self, इसलिए यदि selfब्लॉक का मजबूत संदर्भ है (जो आमतौर पर ऐसा करता है), एक मजबूत संदर्भ चक्र परिणाम। चक्र से बचने के लिए, आपको __blockब्लॉक के बाहर स्वयं को एक कमजोर (या ) संदर्भ बनाने की आवश्यकता है , जैसा कि ऊपर दिए गए उदाहरण में है।

मुझे समझ नहीं आ रहा है कि 'कमजोर (या __block)' का क्या मतलब है?

है

__block typeof(self) tmpSelf = self;

तथा

__weak typeof(self) tmpSelf = self;

यहाँ बिल्कुल वैसा ही?

मुझे दस्तावेज़ में एक और टुकड़ा मिला:

नोट: कचरा-एकत्र किए गए वातावरण में, यदि आप एक चर पर दोनों __weakऔर __blockसंशोधक लागू करते हैं , तो ब्लॉक यह सुनिश्चित नहीं करेगा कि इसे जीवित रखा गया है।

तो, मैं पूरी तरह से हैरान हूँ।

जवाबों:


109

डॉक्स से __ब्लॉक के बारे में

__ब्लॉक वैरिएबल स्टोरेज में रहते हैं जो वैरिएबल के लेक्सिकल स्कोप के बीच साझा किया जाता है और वेरिएबल के लेक्सिकल स्कोप के भीतर घोषित या बनाई गई सभी ब्लॉक्स और ब्लॉक कॉपियां। इस प्रकार, भंडारण स्टैक फ्रेम के विनाश से बचेगा यदि फ्रेम के भीतर घोषित ब्लॉकों की कोई भी प्रतिलिपि फ्रेम के अंत से परे जीवित रहती है (उदाहरण के लिए, बाद के निष्पादन के लिए कहीं और संलग्न होने से)। एक दिए गए लेक्सिकल स्कोप में कई ब्लॉक एक साथ एक साझा चर का उपयोग कर सकते हैं।

डॉक्स से __weak के बारे में

__वेक एक संदर्भ निर्दिष्ट करता है जो संदर्भित वस्तु को जीवित नहीं रखता है। कमजोर संदर्भ को शून्य पर सेट किया जाता है जब ऑब्जेक्ट के लिए कोई मजबूत संदर्भ नहीं होता है।

इसलिए वे तकनीकी रूप से अलग चीजें हैं। __ब्लॉक को अपने वैरिएबल स्कोप से आपके वैरिएबल को अपने ब्लॉक स्कोप में कॉपी करना बंद करना है। __weak एक सेल्फ डिलिटिंग कमजोर पॉइंटर है।

नोट मैंने तकनीकी रूप से कहा, क्योंकि आपके मामले के लिए वे (लगभग) वही काम करेंगे। फर्क सिर्फ इतना है कि आप एआरसी का उपयोग कर रहे हैं या नहीं। यदि आपकी परियोजना ARC का उपयोग करती है और केवल iOS4.3 और इसके बाद के संस्करण के लिए है, तो __weak का उपयोग करें। यह सुनिश्चित करता है कि संदर्भ को शून्य पर सेट किया जाए यदि वैश्विक गुंजाइश संदर्भ किसी तरह जारी होता है। यदि आपकी परियोजना ARC का उपयोग नहीं करती है या पुराने OS संस्करणों के लिए है, तो __block का उपयोग करें।

यहां एक सूक्ष्म अंतर है, सुनिश्चित करें कि आप इसे समझते हैं।

संपादित करें: पहेली का एक और टुकड़ा __unsafe_unretain है। यह संशोधक लगभग __weak जैसा ही है लेकिन पूर्व के ४.३ रनटाइम वातावरणों के लिए है। फिर भी, यह शून्य पर सेट नहीं है और आपको हैंगिंग पॉइंटर्स के साथ छोड़ सकता है।


1
क्या यह अभी भी ARC का उपयोग कर iOS7 के लिए लागू है? मैंने एक प्रोफाइलर चलाया और मैं देखता हूं कि मेरे नियंत्रक तब भी जारी किए जा रहे हैं, जब मैं ब्लॉक में __block या __weak और स्वयं का उपयोग नहीं करता हूं।
जे। क्यू।

1
किसी ऐसे व्यक्ति के लिए जो डॉक देखना चाहता है: developer.apple.com/library/ios/releasenotes/ObjectiveC/… , developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ ...
जून होंग

1
कैसे उन्हें एक साथ उपयोग करने के बारे में? __block _weak NSString *strEg;?
साइबरमेव

5

मैनुअल रेफरेंस काउंटिंग मोड में, __block आईडी x; एक्स को बनाए नहीं रखने का प्रभाव है। एआरसी मोड में, __block आईडी x; एक्स को बनाए रखने के लिए चूक (अन्य सभी मूल्यों की तरह)। एआरसी के तहत मैनुअल रेफरेंस काउंटिंग मोड व्यवहार प्राप्त करने के लिए, आप __unsafe_unretain __block आईडी x का उपयोग कर सकते हैं; जैसा कि नाम __unsafe_unretain का तात्पर्य है, हालांकि, गैर-बनाए गए चर का होना खतरनाक है (क्योंकि यह लटक सकता है) और इसलिए इसे हतोत्साहित किया जाता है। दो बेहतर विकल्प या तो __weak का उपयोग करते हैं (यदि आपको iOS 4 या OS X v10.6 का समर्थन करने की आवश्यकता नहीं है), या रिट चक्र को तोड़ने के लिए __block मान को शून्य पर सेट करें।

सेब डॉक्स



0

ब्लॉक में स्वयं का उपयोग करते समय , __weak का उपयोग करना चाहिए , न कि __ब्लॉक के रूप में यह स्वयं को बनाए रख सकता है।

यदि आपको मजबूत आत्म की आवश्यकता है, तो आप इस तरह का उपयोग कर सकते हैं:

__weak typeof(self) *weakSelf = self;
[self methodThatTakesABlock:^{
    if (weakSelf) {
        __strong typeof(self) *strongSelf = weakSelf;
        [strongSelf doSomething];
    }
}];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.