2012-12-19 21 views
9

में कोई रिपोर्टिंग नहीं है यदि मैं जगह पर कोई ऑटोरेलीज पूल नहीं है तो मैं परिदृश्य पकड़ने की कोशिश कर रहा हूं।
यह मेरा परीक्षण ऐप है।AutoreleasePool ब्रेकपॉइंट्स को पकड़ नहीं रहा, कोई चेतावनी नहीं, इंस्ट्रूमेंट्स लीक्स

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    [self performSelectorInBackground:@selector(bgOperation:) withObject:nil]; 
} 

- (void)bgOperation:(id)obj 
{ 
    NSString *string [[[NSString alloc] init] autorelease]; 
} 

मैंने ब्रेकपॉइंट objc_autoreleaseNoPool को सेट करने का प्रयास किया है।
मैंने उपकरण/लीक के साथ प्रोफाइलिंग करने का प्रयास किया है।
ओएसएक्स 10.7.5 एक्सकोड 4.3.3 लक्ष्य 10.6, स्वचालित रीफकाउंटिंग = नहीं, कचरा चयन = असमर्थित।

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

सुझावों से

अद्यतन:
मैं इस कोशिश की ..
main.m में , कोई भाग्य।

int main(int argc, char *argv[]) 
{ 
    NSString *junk = [[[NSString alloc]init]autorelease]; 
    return NSApplicationMain(argc, (const char **)argv); 
} 

और यह ..
मेरे AppDelegate में, यह भी कोई परिणाम।

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    [NSThread detachNewThreadSelector:@selector(bgOperation:) 
          toTarget:self 
          withObject:nil]; 
} 

और यह ..
मेरी main.m में pthreads

void *doJunk(void *ptr){ 
    NSString *junk = [[[NSString alloc]initWithString:@"string with no pool"]autorelease]; 
    NSLog(@"%@", junk); 
    pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) 
{ 
    pthread_t thread; 
    pthread_create(&thread, NULL, doJunk, NULL); 
    return NSApplicationMain(argc, (const char **)argv); 
} 

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

+0

क्या आपने लॉग में "बस लीकिंग" संदेशों की तलाश की है? –

+0

मैं केवल उन्हें देख सकता हूं जब मैं ऐप चलाता हूं और कंसोल को 10.6 में देखता हूं। – estobbart

उत्तर

5

performSelectorInBackground: शायद आजकल एक प्रेषण_क्यू का उपयोग कर रहा है, जो स्वचालित रूप से आपके लिए एक ऑटोरेलीज पूल सेट करता है। एक नया एनएसटीएचड सीधे लॉन्च करने का प्रयास करें और देखें कि क्या आपके लिए लीक का कारण बनता है।

आप अपने कोड को NSApplicationMain से पहले ले जाने का भी प्रयास कर सकते हैं, जो एक ही व्यवहार होगा।

+0

मेरे द्वारा पढ़े गए सभी दस्तावेज बताते हैं कि प्रत्येक कॉल करने के लिए चयनकर्ता चयन करें: इसे अपने स्वयं के ऑटोोरिज़ पूल की आवश्यकता है। क्या यह कुछ ओएस स्तरों के लिए केवल सच है? – estobbart

+0

यह सच होता था, लेकिन मुझे लगता है कि यह बदल सकता है। –

+0

[NSThread detachNewThreadSelector: @selector (bgOperation :) toTarget: self withObject: nil]; कोई प्रभाव नहीं पड़ा। – estobbart

1

documentation के अनुसार इस स्थिति में पूल बनाना अभी भी अनिवार्य है।

performSelectorInBackground: withObject: विधि एक नया अलग धागा बनाता है और नया थ्रेड के लिए प्रवेश बिंदु के रूप में निर्दिष्ट विधि का उपयोग करता।

[...]

इस विधि बुला के प्रभाव में ही है जैसे कि आप detachNewThreadSelector कहा जाता है: toTarget: withObject: वर्तमान वस्तु, चयनकर्ता, और पैरामीटर के रूप में पैरामीटर वस्तु के साथ NSThread की विधि । नया थ्रेड तुरंत डिफ़ॉल्ट कॉन्फ़िगरेशन का उपयोग करके उत्पन्न होता है और चलना शुरू होता है। चयनकर्ता के अंदर, आपको थ्रेड को कॉन्फ़िगर करना होगा जैसे आप कोई थ्रेड करेंगे। उदाहरण के लिए, आपको एक ऑटोरेलीज पूल (यदि आप कचरा संग्रहण का उपयोग नहीं कर रहे थे) सेट अप करना होगा और थ्रेड के रन लूप को कॉन्फ़िगर करना होगा यदि आपने इसका उपयोग करने की योजना बनाई है।

फिर

+ (void)detachNewThreadSelector:(SEL)aSelector 
         toTarget:(id)aTarget 
        withObject:(id)anArgument 

गैर कचरा-एकत्र अनुप्रयोगों के लिए के लिए NSThread की documentation के अनुसार, विधि aSelector नव अलग थ्रेड के लिए एक autorelease पूल की स्थापना और मुक्त कराने के लिए जिम्मेदार है इससे पहले कि पूल निकलता है।

इसलिए, जब तक कि एप्पल यह (बहुत संभावना नहीं) का दस्तावेजीकरण बिना कार्यान्वयन बदल गया है, बनाने एक पूल अभी भी अनिवार्य एक अलग थ्रेड जो autorelease का उपयोग करता है में मार डाला किसी भी चयनकर्ता के लिए है।

सत्यापित करने के लिए कि क्या दस्तावेज़ सच्चाई बताते हुए है, डॉक दो ऊपर कॉल बराबर होना चाहिए के अनुसार

[NSThread detachNewThreadSelector:@selector(bgOperation:) toTarget:self withObject:nil]; 

के साथ अपने कॉल

[self performSelectorInBackground:@selector(bgOperation:) withObject:nil]; 

को बदलने के लिए प्रयास करें। आप खोज सकते हैं कि वे नहीं हैं।