2009-05-30 6 views
5

मैं एक विधि है कि एक पृष्ठभूमि धागा में चला जाता है बोल रहा हूँ:जब मैं प्रदर्शन करता हूं तो कोई ऑटोरेलीज पूल क्यों नहीं है चयनकर्ता इनबैकग्राउंड :?

- (void) loadViewControllerWithIndex:(NSNumber *)indexNumberObj { 
    NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init]; 
    NSInteger vcIndex = [indexNumberObj intValue]; 

    Class c; 
    UIViewController *controller = [viewControllers objectAtIndex:vcIndex]; 

    switch (vcIndex) { 
     case 0: 
      c = [MyFirstViewController class]; 
      break; 
     case 1: 
      c = [MySecondViewController class]; 
      break; 
     default: 
      NSLog(@"unknown index for loading view controller: %d", vcIndex); // error 
      break; 
    } 

    if ((NSNull *)controller == [NSNull null]) { 
     controller = [[c alloc] initWithNib]; 
     [viewControllers replaceObjectAtIndex:vcIndex withObject:controller]; 
     [controller release]; 
    } 

    if (controller.view.superview == nil) { 
     UIView *placeholderView = [viewControllerPlaceholderViews objectAtIndex:vcIndex]; 
     [placeholderView addSubview:controller.view]; 
    } 

    [arPool release]; 
} 

Althoug मैं वहाँ एक autorelease पूल बना सकता हूँ:

[self performSelectorInBackground:@selector(loadViewControllerWithIndex:) withObject:[NSNumber numberWithInt:viewControllerIndex]]; 

तो, मैं इस विधि कार्यान्वयन चयनकर्ता से बुलाया जाता है कि थ्रेड के लिए, मैं हमेशा इस त्रुटि मिलती है:

2009-05-30 12:03:09.910 Demo[1827:3f03] *** _NSAutoreleaseNoPool(): Object 0x523e50 of class NSCFNumber autoreleased with no pool in place - just leaking 
Stack: (0x95c83f0f 0x95b90442 0x28d3 0x2d42 0x95b96e0d 0x95b969b4 0x93a00155 0x93a00012) 

अगर मैं autorelease पूल दूर ले, मैं इस तरह के संदेशों की एक पूरी गुच्छा मिलता है। मैंने performSelectorInBackground के कॉल के आस-पास एक ऑटोरेलीज पूल बनाने की भी कोशिश की: लेकिन इससे मदद नहीं मिलती है।

मुझे पैरामीटर पर संदेह है, लेकिन मुझे नहीं पता कि संकलक एनएससीएफ संख्या के बारे में शिकायत क्यों करता है। क्या मैं कुछ भूल रहा हूँ?

मेरा इंस्टेंस वैरिएबल सभी "nonatomic" हैं। क्या यह एक समस्या हो सकती है?

अद्यतन: मुझे यह भी संदेह हो सकता है कि कुछ चर को मुख्य धागे (शायद एक ivar) के एक ऑटोरेलीज पूल में जोड़ा गया है, और अब यह गलत ऑटोरेलीज पूल के अंदर इसे रिलीज़ करने की कोशिश करता है? यदि हां, तो मैं इसे कैसे ठीक कर सकता हूं? (अरे, यह थ्रेडिंग सामान जटिल है;))

+0

एक ब्रेकपाइंट सेट करने का प्रयास _NSAutoreleaseNoPool पर यह देखने के लिए कि इसे – rpetrich

+0

से कहां से बुलाया जा रहा है टेंगेंट प्रश्न: यहां इस धागे में स्थानीय रूप से आवंटित एक नया नियंत्रक, वैश्विक सरणी में जोड़ा गया है और इसके दृश्य को सबव्यूव के रूप में जोड़ा गया है। क्या यह एक समस्या है कि वस्तु अपने कंटेनर की तुलना में एक अलग पूल में बनाई गई है? –

+0

@ डीके आपको एक स्पर्शपूर्ण सवाल नहीं पूछना चाहिए, एक अलग सवाल पूछें! वैसे भी मैं दृढ़ता से यूआई संबंधित वस्तुओं (नियंत्रकों और विचारों) को गैर-मुख्य धागे में बनाने के खिलाफ सलाह देता हूं। यह एक आपदा होने का इंतजार कर रहा है। – Yuji

उत्तर

6

इसकी संभावना सबसे अधिक कारण है क्योंकि लीक ऑब्जेक्ट (एनएसएनंबर), थ्रेड के बाहर से एक पैरामीटर पास किया गया है। इसलिए, यह चर कॉलिंग थ्रेड (और इसके ऑटोरेलीज पूल) से संबंधित है

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

मेरा सुझाव है कि आप इसे तर्क के रूप में पास करने के बाद अपने चयनकर्ता के पैरामीटर पर रिलीज़ करें।

+1

हां, नए धागे में ऑटोरेलेज्ड ऑब्जेक्ट्स को गुजरने से बहुत अजीब व्यवहार हो सकता है। –

2

मैं मानता हूं कि इसका कारण यह है कि लीक ऑब्जेक्ट (एनएसएनंबर), थ्रेड के बाहर से पारित पैरामीटर है। इसलिए, इस चर बुला धागा (और इसके autorelease पूल)

बुला धागा NSAutoreleasePool का उपयोग करना चाहिए के अंतर्गत आता है और मेरा सुझाव है कि आप के रूप में अपने पैरामीटर के लिए एक बनाए रखने के निर्देश जोड़ें:

- (void) loadViewControllerWithIndex:(NSNumber *)indexNumberObj { 
    NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init]; 
    [indexNumberObj retain]; 

    .... 

    [arPool release]; 
    }