आप से पूछा:
मान लिया जाये कि weakSelf
गैर nil
जब संदेश भेजा जाता है, यह है, जबकि doSomeAction
काम कर रहा है पुनः आवंटित की जाती हो सकता है या यह doSomeAction
रिटर्न जब तक वैध रहेगा करने की गारंटी है?
हां, न केवल doSomeAction
रिटर्न तक वैध रहता है, यह शेष ब्लॉक के लिए भी बनाए रखा जाता है। निम्नलिखित पर विचार करें:
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
- (void)startBackgroundOperation
{
__weak MyObject * weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[weakSelf doSomeAction];
sleep(5);
[weakSelf doSomeAction2];
});
sleep(1);
}
- (void)doSomeAction
{
NSLog(@"%s", __FUNCTION__);
}
- (void)doSomeAction2
{
NSLog(@"%s", __FUNCTION__);
}
इस उदाहरण में, मुझे यकीन है कि वस्तु गुंजाइश जब ब्लॉक शुरू होता है में किया गया था, लेकिन यह doSomeAction
और doSomeAction2
के बीच दायरे से बाहर हो जाते हैं, लेकिन ब्लॉक के लिए यह बनाए रखने के लिए प्रकट होता है ब्लॉक का समापन लेकिन अगर मैं doSomeAction
के आविष्कार पर टिप्पणी करता हूं, तो weak
संदर्भ nil
है, जब तक यह doSomeAction2
पर आता है, जैसा कि आप उम्मीद करेंगे।
एक अलग रूप में के रूप में, WWDC 2011 - #322 - Objective-C Advancements In-Depth में, वे (वीडियो में के बारे में 27:00 मिनट) का कहना है, वे बताते हैं कि अगर आप weakSelf
अपसंदर्भन रहे हैं, आप प्रेषण ब्लॉक के अंदर एक स्थानीय मजबूत संदर्भ होना चाहिए अपने आप को रेस स्थिति में की रक्षा के लिए, इस प्रकार:
__weak MyClass *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
MyClass *strongSelf = weakSelf;
if (strongSelf)
[strongSelf->myView doSomeViewAction];
});
कि यह ब्लॉक की अवधि के लिए बनाए रखेगी (यह मानते हुए पहले से ही समय ब्लॉक मार डाला गया था द्वारा पुनः आवंटित की जाती नहीं गया था)।
यह मेरे लिए एक कार्यान्वयन quirk की तरह लगता है; मुझे संदेह है कि यह कहीं भी दस्तावेज/गारंटीकृत है। :) –
@ रोब: स्टीवन ने कहा कि यह निश्चित रूप से एक कार्यान्वयन quirk है। कंपाइलर संभवतः 'objc_loadWeak()' का उपयोग करता है, जो 'objc_loadWeakRetained()' की बजाय मान को स्वत: करता है, जो नहीं करता है। आप इस व्यवहार पर भरोसा नहीं कर सकते, क्योंकि यह अनुकूलन स्तर या कंपाइलर के भविष्य के संस्करणों के साथ बदल सकता है। –
एक अनुवर्ती प्रश्न: क्या ऐप्पल एलएलवीएम 5.0 में "__weak पॉइंटर्स को चेतावनी संदेश" चेतावनी प्रदान करता है? मुझे लगता है कि "एक __weak संदर्भ का बार-बार उपयोग करना" एक अलग चेतावनी है। जब तक कोई अनुकूलन न हो, जहां तर्कों का मूल्यांकन करने से पहले 'शून्य' जांच होती है (यानी, यह 'objc_msgSend' में नहीं होता है)? – Tommy