2013-01-02 36 views
9

संभव डुप्लिकेट:
Why do weak NSString properties not get released in iOS?ऑब्जेक्टिव-सी: कमजोर attritube अपेक्षा के अनुरूप काम नहीं करते

मैं उद्देश्य सी के लिए एक नौसिखिया हूँ और मैं कुछ सवाल मिल गया है कि मैं खुद का जवाब नहीं दे सकता ,

NSString *myString = [[NSString alloc] initWithFormat:@"John"]; 
NSString * __weak weakString = myString; 
myString = nil; //<-- release the NSString object 
NSLog(@"string: %@", weakString); 

ऊपर कोड के उत्पादन की उम्मीद है के रूप में के बाद से weakString एक कमजोर चर रहा है: मैं (मैं, एआरसी उपयोग कर रहा हूँ निश्चित रूप से) परीक्षण __weak चर के लिए कोड का एक खंड है

2013-01-02 11:42:27.481 ConsoleApp[836:303] string: (null) 

लेकिन जब मैं यह करने के लिए कोड संशोधित:

NSString *myString = [[NSString alloc] initWithFormat:@"John"]; 
NSString * __weak weakString = myString; 
NSLog(@"Before: %@", weakString); //<--- output to see if the __weak variable really works. 
myString = nil; 
NSLog(@"After: %@", weakString); 

उत्पादन पूरी तरह से नहीं है कि मैं क्या उम्मीद:

2013-01-02 11:46:03.790 ConsoleApp[863:303] Before: John 
2013-01-02 11:46:03.792 ConsoleApp[863:303] After: John 

उत्तरार्द्ध एनएसएलओजी का उत्पादन "जॉन" के बजाय (शून्य) होना चाहिए। मैंने कई दस्तावेजों में खोज करने की कोशिश की है लेकिन मुझे इस मामले का जवाब नहीं मिला है। क्या कोई उचित व्याख्या दे सकता है? अग्रिम में धन्यवाद।

+0

@jrturton: मुझे नहीं लगता कि इस लिंक किए गए सवाल का डुप्लिकेट है है। मुद्दा निरंतर 'एनएसएसटींग' का उपयोग कर रहा था जो प्रदर्शन अनुकूलन के कारण सामान्य स्मृति प्रबंधन में भाग नहीं लेता है। इस मुद्दे को ठीक से टालने के लिए यहां पोस्टर 'initWithFormat' का उपयोग करता है। – zoul

+0

मैंने पढ़ा है (लेकिन इस बार नहीं मिला) इस का एक और डुप्लिकेट जहां एनएसएसटींग का कुछ अनुकूलन इस काम को रोकता है। यदि ओपी एक अलग प्रकार की वस्तु की कोशिश करता है, तो मुझे संदेह है कि सब कुछ अपेक्षित काम करेगा। मैं खोज रखूंगा ... – jrturton

+0

यहां भी: http://stackoverflow.com/questions/9202810/lifetime-of-weak-local-variables-with-arc – jrturton

उत्तर

6

NSLog फ़ंक्शन एक ऑटोरेलीज पूल में उत्तीर्ण एनएसएसटींग को बनाए रख रहा है। इसलिए शून्य-कमजोर चर को तब तक शून्य नहीं किया जाएगा जब तक ऑटोरेलीज पूल नहीं निकलता है। उदाहरण के लिए:

__weak NSString* weakString = nil; 

@autoreleasepool { 
    NSString* myString = [[NSString alloc] initWithFormat:@"Foo"]; // Retain count 1 
    weakString = myString;   // Retain count 1 
    NSLog(@"A: %@", weakString); // Retain count 2 
    NSLog(@"B: %@", weakString); // Retain count 3 
    myString = nil;    // Retain count 2 
    NSLog(@"C: %@", weakString); // Retain count 3 

    NSAssert(weakString != nil, @"weakString is kept alive by the autorelease pool"); 
} 

// retain count 0 
NSAssert(weakString == nil, @"Autorelease pool has drained."); 

NSLog स्ट्रिंग को ऑटोरेलीज पूल में क्यों डाल रहा है? यह एक कार्यान्वयन विस्तार है।

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

+1

हाँ, यह काफी समझाया गया, मैं सोच रहा था कि एनएसएलओएल() इसके पैरामीटर की बरकरार गिनती को बढ़ाएगा, लेकिन आपका जवाब अधिक उचित है। बहुत बहुत धन्यवाद डैरेन। –

0

मुझे लगता है कि यह केवल कुछ कार्यान्वयन विस्तार है। आपका कमजोर चर साफ़ हो रहा है, लेकिन तुरंत नहीं। उदाहरण के लिए, इस के रूप में की उम्मीद काम करता है:

NSString *myString = [[NSString alloc] initWithFormat:@"John"]; 
NSString * __weak weakString = myString; 
@autoreleasepool { 
    NSLog(@"Before: %@", weakString); 
    myString = nil; 
} 
NSLog(@"After: %@", weakString); // nil