2009-05-16 14 views
12

कौन सही है? यह:मेमोरी प्रबंधन और performSelectorInBackground:

NSArray* foo = [[NSArray alloc] initWithObjects:@"a", @"b", nil]; 
[bar performSelectorInBackground:@selector(baz:) withObject:foo]; 

- (void)baz:(NSArray*)foo { 
    ... 
    [foo release]; 
} 

या:

NSArray* foo = [[[NSArray alloc] initWithObjects:@"a", @"b", nil] autorelease]; 
[bar performSelectorInBackground:@selector(baz:) withObject:foo]; 

- (void)baz:(NSArray*)foo { 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
    ... 
    [pool release]; 
} 

मैं पहली बार एक काम करता है पता है, लेकिन बजना इसके बारे में शिकायत है, तो मुझे आश्चर्य है कि उपयोग करने के लिए एक बेहतर पैटर्न मौजूद है या।

मैं 2 एक "सिर्फ बाहर की कोशिश" होगा, लेकिन autoreleasing साथ, कौन जानता है कि क्या EXC_BAD_ACCESS की अनुपस्थिति का मतलब है कि आप इसे सही कर रहे हैं या कि तुम सिर्फ भाग्यशाली ...

उत्तर

24

पहले गलत है ।

प्रदर्शन चयनकर्ताबैकग्राउंड: ऑब्जेक्ट: कार्य पूरा होने तक बार और फू दोनों को बरकरार रखता है। इस प्रकार, जब आप इसे बनाते हैं तो आपको autorelease foo करना चाहिए और प्रदर्शन करने में मदद करें SelectorInBackground: ऑब्जेक्ट बाकी की देखभाल करें। documentation

लेटर सही है क्योंकि जब आप इसे बनाते हैं तो आप स्वत: फूज करते हैं। आपके द्वारा बज़ के अंदर बनाए गए ऑटोोरिज़ पूल में फू के मेमोरी प्रबंधन की शुद्धता के साथ कुछ भी नहीं है। यही कारण है कि autorelease पूल autoreleased वस्तुओं पूल आवंटन के अंदर के लिए आवश्यक और baz में जारी है, यह स्पर्श नहीं करता है foo के बिल्कुल गिनती बरकरार रहती है।

+1

ओह, यह दस्तावेज में वहीं है! मुझे मूर्ख। :) – lawrence

+4

मैं स्पष्ट करना चाहिए: आप -baz अंदर बना सकते हैं और नाली चाहिए एक autorelease पूल :, जब तक आप जानते हैं कि कुछ भी नहीं के अंदर वहाँ एक -autorelease विधि भेजा जाएगा। अंगूठे का सबसे अच्छा नियम यह मानना ​​है कि ऐसा होगा और एक ऑटोरेलीज पूल बनाएं/निकालें, उदाहरण के लिए 2. लेकिन [पूल नाली] का उपयोग करें, [पूल रिलीज] नहीं। –

+0

जिम डोवी ने बिल्कुल कहा: आपको आमतौर पर मुख्य कार्य के लिए ऑटोरेलीज पूल बनाने की आवश्यकता होती है (थ्रेड प्रोग्रामिंग गाइड देखें)। यह समझना बहुत महत्वपूर्ण है कि इस पूल के पास foo के autorelease के साथ कुछ लेना देना नहीं है। –

2

सही दृष्टिकोण अब वास्तव में क्या करना होगा:

NSArray* foo = [[[NSArray alloc] initWithObjects:@"a", @"b", nil] autorelease]; 
[bar performSelectorInBackground:@selector(baz:) withObject:foo]; 

- (void)baz:(NSArray*)foo { 
    @autoreleasepool { 
     ... 
    } 
} 
संबंधित मुद्दे