5

में __weak और __strong उपयोग कारण बताएं मुझे लगता है कि मैं मजबूत और कमजोर कीवर्ड अच्छी तरह से समझता हूं, लेकिन मुझे समझ में नहीं आता कि यह नीचे दिए गए कोड में कैसे उपयोग किया जाता है। यह कोड एसडीवेब इमेज से ओलिवियर पोइट्रे द्वारा जिथब पर उपलब्ध है। मैं यहां वर्णित मजबूत और कमजोर कीवर्ड समझता हूं: Explanation of strong and weak storage in iOS5SDWebImage कोड

नीचे दिया गया कोड __weak और __strong कीवर्ड का उपयोग करता है जो मेरे लिए उत्सुक है। यह बाल-अभिभावक संबंध या प्रतिनिधि पैटर्न नहीं है क्योंकि मुझे कमजोर इस्तेमाल करने के लिए उपयोग किया जाता है। हालांकि, मुझे यकीन है कि यह एक ऐसा पैटर्न है जिसका प्रयोग अक्सर किया जाता है, क्योंकि मैंने इसे दूसरे कोड में पहले देखा है। यह एक ब्लॉक से पहले एक __weak संदर्भ सेट करता है जो किसी अन्य धागे पर चलता है। फिर, ब्लॉक के भीतर, यह एक मजबूत संदर्भ के लिए कमजोर संदर्भ सेट करता है।

मुझे यकीन है कि यह अच्छा और सुरुचिपूर्ण कोड है, इसलिए मैं इसे समझने की कोशिश कर रहा हूं। यदि ब्लॉक चलाने से पहले "स्वयं" अस्तित्व में रहता है, तो कमजोर आत्म संदर्भ शून्य हो जाएगा। जब ब्लॉक चलता है, तो मजबूत संदर्भ शून्य पर भी सेट किया जाएगा। इसलिए, यह शेष ऑपरेशन को मारने के बारे में पता चलेगा क्योंकि स्वयं अब अस्तित्व में नहीं है। क्या मुझे यह अधिकार मिला?

अब, अगर हम __weak और __strong कीवर्ड का उपयोग नहीं करते तो क्या होगा? क्या होगा यदि हमने अभी ब्लॉक के अंदर जांच की है कि क्या स्वयं == शून्य है। ब्लॉक "पूरे" कभी भी शून्य नहीं होगा क्योंकि ब्लॉक पूरे पेड़ की प्रतिलिपि बनाता है?

क्या कोई इस कोड के इस अद्भुत टुकड़े को नष्ट करने में मदद कर सकता है? क्या कोई मेरी परिकल्पनाओं को सत्यापित या अस्वीकार कर सकता है?

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock; 
{ 
    [self cancelCurrentImageLoad]; 

    self.image = placeholder; 

    if (url) 
    { 
     __weak UIImageView *wself = self; 
     id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) 
     { 
      __strong UIImageView *sself = wself; 
      if (!sself) return; 
      if (image) 
      { 
       sself.image = image; 
       [sself setNeedsLayout]; 
      } 
      if (completedBlock && finished) 
      { 
       completedBlock(image, error, cacheType); 
      } 
     }]; 
     objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
    } 
} 

उत्तर

7

downloadWithUrl: विधि में काफी समय लग सकता है। उस समय, उपयोगकर्ता SDWebImage ऑब्जेक्ट की आवश्यकता को समाप्त करने, दूर नेविगेट करने का निर्णय ले सकता है। वस्तु के प्रारंभिक सफाई को सुविधाजनक बनाने के लिए, बाहरी self संदर्भ कमजोर है। इस तरह, downloadWithUrl को को हटाए जाने से नहीं रोकेगा।

बेशक, यदि आप वास्तव में self के साथ काम करना चाहते हैं, तो आपको एक मजबूत संदर्भ की आवश्यकता है। इसलिए, downloadWithUrl पर पूरा होने वाला ब्लॉक self पर एक मजबूत संदर्भ प्राप्त करता है। यदि इस समय वस्तु दूर हो जाती है, sselfnil होगा। अन्यथा, यह एक मान्य मजबूत संदर्भ होगा, जो दर्शाता है कि SDWebImage ऑब्जेक्ट अभी भी आसपास है, और ऑब्जेक्ट इस समय अपना काम पूरा कर देगा।

+0

एक और शानदार जवाब। धन्यवाद nneonneo। –

+1

यह "ऑब्जेक्ट की प्रारंभिक सफाई को सुविधाजनक बनाने के लिए" से अधिक है। यह वस्तु की सफाई को सुविधाजनक बनाता है - अन्यथा एक सतत चक्र होगा - 'स्वयं' सहयोगी संदर्भ के माध्यम से 'ऑपरेशन' को बनाए रखता है। 'ऑपरेशन' ब्लॉक को बरकरार रखता है। यदि ब्लॉक 'स्वयं' बनाए रखा गया तो यह एक चक्र होगा। – newacct

3

मुझे यकीन है कि यह अच्छा और सुरुचिपूर्ण कोड है, इसलिए मैं इसे समझने की कोशिश कर रहा हूं। यदि ब्लॉक चलाने से पहले "स्वयं" अस्तित्व में रहता है, तो कमजोर आत्म संदर्भ शून्य हो जाएगा। जब ब्लॉक चलता है, तो मजबूत संदर्भ शून्य पर भी सेट किया जाएगा। इसलिए, यह शेष ऑपरेशन को मारने के बारे में पता चलेगा क्योंकि स्वयं अब अस्तित्व में नहीं है। क्या मुझे यह अधिकार मिला?

नहीं, आप इसे थोड़ा सा सोच रहे हैं। __weak स्टोरेज क्वालीफायर बस यही है: एक क्वालीफायर। ऑब्जेक्ट्स जो __weak स्पष्ट रूप से अप्रत्याशित हैं, लेकिन यदि वे एक मजबूत चर से असाइन किए गए हैं तो वे स्वचालित रूप से शून्य पर सेट नहीं होते हैं। वास्तव में, यह एक कमजोर चर के उद्देश्य को हरा देगा!

अब, अगर हम __weak और __strong कीवर्ड का उपयोग नहीं करते तो क्या होगा? क्या होगा यदि हमने अभी ब्लॉक के अंदर जांच की है कि क्या स्वयं == शून्य है। ब्लॉक "पूरे" कभी भी शून्य नहीं होगा क्योंकि ब्लॉक पूरे पेड़ की प्रतिलिपि बनाता है?

जांच वास्तव में अनावश्यक है क्योंकि रनटाइम संदेशों को शून्य तक शून्य करने के लिए हल करता है (फिर भी, बाद में कार्यान्वयन के लिए यह महत्वपूर्ण हो सकता है, कौन जानता है)।आप इस के साथ स्पॉट पर हैं: उस छोटे से "मजबूत करने के लिए कमजोर" नृत्य के बिना, फिर स्वयं को एक बहुत ही बुरा बरकरार चक्र बनाने की क्षमता के साथ, ब्लॉक द्वारा बनाए रखा जाएगा। जहां मैं इसे सब एक साथ जोड़ना शुरू कर सकता हूं:

क्योंकि हम नहीं चाहते हैं कि ब्लॉक हमारे चर को बरकरार रखे, लेकिन हम भी ब्लॉक के दायरे में मजबूत होना चाहते हैं, इसलिए अजीब कुछ नहीं होता है, स्वयं को असाइन किया जाता है एक कमजोर सूचक के लिए। जब हमारे कमजोर सूचक पर ब्लॉक होता है, तो इसे बनाए रखने की अनुमति नहीं होती है, इसलिए स्वयं की संदर्भ गणना एक ही रहती है, फिर एक बार ब्लॉक के अंदर, हम एक मजबूत आत्म परिवर्तनीय पर वापस जाते हैं ताकि कमजोर व्यक्ति को रिहा कर दिया जा सके, और हम इसके बारे में चिंता करने की ज़रूरत नहीं है। व्यावहारिक रूप से, इसका मतलब है कि हमारे पास ठोस गारंटी है कि स्वयं ब्लॉक के पूरे निष्पादन में मूल्य या शून्य है। बहुत साफ, हुह?

+0

आपका अंतिम अनुच्छेद बहुत उपयोगी है। धन्यवाद कोडाफ़ी। –

+0

मुझे इस वाक्यांश को समझ में नहीं आया: "... हम एक मजबूत आत्म चर के लिए वापस जाते हैं ताकि कमजोर व्यक्ति को रिहा कर दिया जा सके"। क्या यह सुनिश्चित करने के लिए एक मजबूत संदर्भ बनाने के लिए स्वयं है कि ब्लॉक को किसी अन्य थ्रेड द्वारा ब्लॉक निष्पादित करने के बीच में रिलीज़ नहीं किया जाएगा? – Boon

+1

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