/ / एक कमजोर चक्र को बनाए रखने के चक्र को बनाए रखने के बिना डीललॉक्ड होने से रोकें

एक कमजोर असाइन किए गए वैरिएबल को बनाए रखने के चक्र को बनाए रखने से रोकें - कोको-टच, कोको, स्वचालित-रेफ-गिनती, ऑब्जेक्ट-सी-ब्लॉक, एनएसएनोटिफिकेशनर

मेरे पास ARC, NSNotificationCenter और एक ब्लॉक से जुड़ा एक अजीब मामला है। निम्नलिखित कोड का एक सरलीकृत उदाहरण है। परीक्षण से ऐसा लगता है कि स्मृति प्रबंधन didSaveObserver वांछित के रूप में प्रदर्शन कर रहा है, अर्थात् यह एक अनुवर्ती चक्र नहीं बना रहा है और यह नहीं हो रहा है nilपहले एड removeObserver:.

हालाँकि, ARC के बारे में मेरी समझ से मुझे लगता है कि यह सिर्फ एक फ्लूक / क्विक है और ARC कर सकता है nil didSaveObserver से पहले removeObserver:। के रूप में देख didSaveObserver कभी नहीं रखा जाता है (केवल असाइनमेंट है a weak चर), तो एआरसी / (चाहिए?) तुरन्त इसे निपटाना चाहिए।

क्या मैंने एआरसी नियमों को सही ढंग से समझा है? यदि ऐसा है तो मैं यह कैसे सुनिश्चित करूँ कि didSaveObserver को बरकरार रखा जाता है, ताकि इसे अनबॉर्स्ड किया जा सके लेकिन रिटेन साइकिल नहीं बनाया जाए?

self.willSaveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextWillSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {

id preSaveState = ...; //Store some interesting state about a Core Data object (the details aren"t significant to this question).

__weak __block id didSaveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
//Unobserve the did save block. This is the tricky bit! didSaveObserver must be __weak to avoid a retain cycle, but doing so also means that the block may be dealloced before it can be unobsered.
[[NSNotificationCenter defaultCenter] removeObserver:didSaveObserver];

id postSaveState = ...;
//Perform work that uses pre & post save states.
}];
}];

अधिक जानकारी:

अगर __weak जोड़ा नहीं गया है (इसलिए चूक __strong) उपकरण रिपोर्ट करते हैं कि एक चक्र बरकरार है।

उत्तर:

जवाब के लिए 0 № 1

NSNotification.h में एक टिप्पणी है जो बताती है कि क्यों didSaveObserver isn "t इस विशेष मामले में निपटाया:

// The return value is retained by the system, and should be held onto by the caller in
// order to remove the observer with removeObserver: later, to stop observation.

बेशक, यह केवल इस विशिष्ट मामले की व्याख्या करता है।


जवाब के लिए 0 № 2

सबसे पहले, आपको क्यों लगता है कि यह एक चक्र बनाएगा? ब्लॉक बरकरार रहेगा didSaveObserver, हाँ। चाहेंगे didSaveObserver ब्लॉक बनाए रखें? लौटे प्रेक्षक वस्तु के बारे में कुछ भी प्रलेखित नहीं किया जाता है, इसके अलावा इसका उपयोग किया जा सकता है removeObserver: जोड़ा अवलोकन हटाने के लिए। यह संभव है कि यह किसी तरह ब्लॉक को बनाए रखता है या ब्लॉक ही होता है, इस स्थिति में यह एक चक्र बनाए रखेगा। यदि आप सुरक्षित रहना चाहते हैं, हाँ, आप उपयोग कर सकते हैं weak ब्लॉक में पर्यवेक्षक को संदर्भित करने के लिए।

DidSaveObserver के रूप में देखना कभी भी बरकरार नहीं रहता (केवल असाइनमेंट ही है) एक कमजोर चर), तब एआरसी / (चाहिए?) तुरन्त इसे निपटा सकता है।

जब तक कि आपके पास लौटने से पहले अधिसूचना केंद्र द्वारा इसे बरकरार रखा जाता है।