6

मैंने देखा है निम्न प्रयोग किया है:मैं dispatch_after() को पास किए गए ब्लॉक में स्वयं को कमजोर सूचक का उपयोग क्यों नहीं करूंगा?

double delayInSeconds = 2.0; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    //code to be executed on the main queue after delay 
    [self doSometingWithObject:obj1 andAnotherObject:obj2]; 
}); 

लेकिन यह ब्लॉक में कमजोर स्वयं उपयोग नहीं करना चाहिए?

__weak typeof(self) weakSelf = self; 
double delayInSeconds = 2.0; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    //code to be executed on the main queue after delay 
    [weakSelf doSometingWithObject:obj1 andAnotherObject:obj2]; 
}); 

मैं जीसीडी और ब्लॉक के लिए नया हूं और सबसे सही उपयोग करने की कोशिश कर रहा हूं। इस पर किसी भी मार्गदर्शन पर बहुत धन्यवाद। ब्लॉक का उपयोग करने का

+2

यह निर्भर करता है। क्या आपको व्यू कंट्रोलर को खारिज करने के बाद भी 'doSometingWithObject' [sic] को कॉल करने की आवश्यकता है? कभी-कभी आप करते हैं (उदाहरण के लिए शायद आप कुछ सहेज रहे हैं, मॉडल ऑब्जेक्ट अपडेट कर रहे हैं, कुछ महत्वपूर्ण नेटवर्क अनुरोध पोस्ट कर रहे हैं, जो भी हो), इस मामले में आप पूर्व वाक्यविन्यास का उपयोग करेंगे। लेकिन कभी-कभी आप नहीं करते (उदा। आप कुछ यूआई ऑब्जेक्ट को उस दृश्य पर अपडेट करना चाहते हैं जो पहले से ही खारिज कर दिया गया हो), इस मामले में आप बाद वाले का उपयोग करेंगे। – Rob

+1

यह इस बात पर निर्भर करता है कि आप क्या करना चाहते हैं यदि देरी होने से पहले 'स्वयं' को हटाए जाने का मौका मिलता है। पहला स्निपेट उसको रोक देगा, इसलिए ब्लॉक में कॉल हमेशा होता है जहां दूसरा व्यक्ति स्वयं को डिलीकेट किया जा सकता है और ब्लॉक कुछ भी नहीं करेगा। आम तौर पर कमजोर आत्म का उपयोग चक्र को बनाए रखने से रोकने के लिए किया जाता है लेकिन इस ब्लॉक में – dan

उत्तर

6

यह वांछित व्यवहार पर निर्भर करता है।

  • पहले वाक्य रचना (ब्लॉक में self के संदर्भ में) dispatch_after आग जब तक दृश्य नियंत्रक के लिए एक मजबूत संदर्भ बनाए रखेंगे और doSometingWithObject सफलतापूर्वक चला। यह तब भी होगा जब उस व्यू कंट्रोलर से जुड़े दृश्य को मध्यवर्ती अवधि में खारिज कर दिया जाता है।

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

  • दूसरा वाक्य रचना, दृश्य नियंत्रक के लिए एक मजबूत संदर्भ बनाए रखने नहीं होगा, और इस प्रकार यदि दृश्य नियंत्रक से जुड़े दृश्य को ब्लॉक के समय तक खारिज कर दिया गया था, तो दृश्य नियंत्रक जारी किया जाएगा और weakSelfnil होगा, और इस प्रकार doSometingWithObject नहीं कहा जाएगा। (जाहिर है, यदि दृश्य को अभी तक बर्खास्त कर दिया गया है, दृश्य नियंत्रक जारी किया गया है नहीं होगा, weakSelf नहीं nil होगा और कहा कि विधि बुलाया जाएगा।)

    आप क्या करेंगे कि करने के लिए करता है, तो सवाल में विधि केवल जरूरत है अगर कॉल अभी तक खारिज नहीं किया गया है तो बुलाया जाए। उदाहरण के लिए, यदि विधि का एकमात्र उद्देश्य उस दृश्य पर कुछ UI ऑब्जेक्ट को अपडेट करना है, तो आपको स्पष्ट रूप से उस विधि को कॉल करने की आवश्यकता नहीं है यदि दृश्य पहले से ही खारिज कर दिया गया है। और उस परिदृश्य में, आप आम तौर पर weakSelf का उपयोग करना पसंद करेंगे ताकि दृश्य नियंत्रक को तत्काल रिलीज़ किया जा सके जब इसकी आवश्यकता नहीं होती है।

  • बस पूर्णता के लिए के लिए

    , वहाँ वास्तव में इस पद्धति का एक तिहाई क्रमचय है, कभी कभी (मजाक) weakSelf/strongSelf "नृत्य" कहा जाता है:

    __weak typeof(self) weakSelf = self; 
    double delayInSeconds = 2.0; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
        //code to be executed on the main queue after delay 
        typeof(self) strongSelf = weakSelf; 
        if (strongSelf) { 
         [strongSelf doSomethingWithObject:obj1 andAnotherObject:obj2]; 
         [strongSelf doSomethingElseWithObject:obj1]; 
        } 
    }); 
    

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

-2

बेहतर हिस्सा इस तरह है:

__weak typeof(self) weakSelf = self; 
double delayInSeconds = 2.0; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    //code to be executed on the main queue after delay 
    __strong __typeof(weakSelf)strongSelf = weakSelf; 
    [strongSelf doSometingWithObject:obj1 andAnotherObject:obj2]; 
}); 

ब्लॉक के भीतर __strong संदर्भ बनाना स्मृति संदर्भ संख्या में वृद्धि नहीं होगी। एक बार ब्लॉक पूरा हो जाने पर इसे रिहा कर दिया जाएगा।

https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/

+0

ब्लॉक के भीतर '__strong' संदर्भ * संदर्भ संख्या में वृद्धि करता है - लेकिन केवल ब्लॉक चल रहा है। ब्लॉक समाप्त होने के बाद यह फिर से गिनती को कम करेगा। – Nef10

2

आत्म करने के लिए एक कमजोर सूचक चक्र को बनाए रखने को रोकने के लिए प्रयोग किया जाता है। पहले कोड स्निपेट में एक बनाए रखने चक्र का कोई खतरा नहीं है।

एक बनाए रखने के चक्र एक चिंता का विषय हो सकता है अगर आपके वस्तु ब्लॉक जो आपके वस्तु, और अगर आपके वस्तु केवल ब्लॉक रिलीज करने के लिए जब वह खुद को पुनः आवंटित की जाती जा रहा था को बरकरार रखे हुए बनाए रखने के लिए कर रहे थे। इन शर्तों में से कोई भी इस मामले में नहीं है।

dispatch_after() नामित समय के बाद प्रदान किए गए ब्लॉक को चलाएगा और फिर ब्लॉक जारी करेगा। ब्लॉक की रिलीज आपके ऑब्जेक्ट को डिलीओटेड पर निर्भर नहीं है। कोई बरकरार चक्र नहीं है।

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