10

के तहत किसी ऑब्जेक्ट को डिलीकेट करने के लिए मजबूर करना मैं एक आईपैड फोटो कोलाज ऐप पर काम कर रहा हूं जो स्क्रीन पर शायद सैकड़ों UIImageView एस को खींचता है।एआरसी

एक बटन उपयोगकर्ता "फिर से बनाने" है, जो सभी तस्वीरें पर [photo removeFromSuperview] करने के लिए एक for पाश चलाने के लिए और फिर एक नया बैच प्रारंभ करने में लगता है की सुविधा देता है, इसी क्रम में नहीं है।

मैं एआरसी का उपयोग कर रहा हूं, और मेरा कंसोल मुझे बताता है कि मेरा Photo की dealloc विधि को तब तक नहीं बुलाया जा रहा है जब तक कि अगले बैच तैयार नहीं किया जाता है, जिसका अर्थ है कि मैं स्मृति समस्याओं में भाग रहा हूं, भले ही मैं अगले सेट को जोड़ने से पहले पहले सेट को हटाने का प्रयास कर रहा है।

क्या कोई तरीका है 1) प्रतीक्षा करें जब तक कि सभी फ़ोटो ठीक से डिलीक नहीं किया गया हो या 2) सभी तस्वीरों को तुरंत एआरसी के तहत डीलोक करने के लिए मजबूर करें?

+1

राडू सही है कि एक बार जब आप छवि दृश्य हटा देते हैं और उन सभी मजबूत संदर्भों को हटा देते हैं, तो उन्हें तुरंत हटा दिया जाएगा। यह पुराने एमआरसी मुद्दे की तरह नहीं है जहां 'ऑटोरेलीज' के मैला उपयोग के परिणामस्वरूप वर्तमान रन लूप के अंत तक स्मृति की रिलीज का स्थगित हो सकता है। यदि आपको अभी भी समस्याएं आ रही हैं, तो आपको छवियों और उनके छवि दृश्यों के किसी भी संदर्भ को बनाने, जोड़ने और सहेजने के लिए हमें कोड स्निपेट दिखाने की आवश्यकता होगी। लेकिन अगर मैं छवि दृश्य को हटाता हूं और नया बना देता हूं, तो पुराने के लिए डेलोक एक नया निर्माण करने से पहले होता है। – Rob

उत्तर

13

आप शायद इसे बिना किसी एटोरिज़ पूल में अपने चित्र दृश्य डाल रहे हैं। आप अपने फोर-लूप के आस-पास अपने स्वयं के ऑटोरेलीज पूल को लपेटकर इसे ठीक करने में सक्षम हो सकते हैं।

उदाहरण के लिए, मैंने एक छवि दृश्य के साथ एक बहुत ही सरल परीक्षण परियोजना बनाई और मेरे शीर्ष-स्तर के दृश्य के नीचे एक बटन बनाया। जब मैं बटन टैप करता हूं, तो यह छवि दृश्य को हटा देता है और एक नया बनाता है। यह शीर्ष-स्तरीय दृश्य के उप-दृश्यों पर लूप करके छवि दृश्य को हटा देता है। कोड यह रहा:

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self initImageView]; 
} 

- (IBAction)redoWasTapped:(id)sender { 
    [self destroyImageView]; 
    [self initImageView]; 
} 

- (void)destroyImageView { 
    for (UIView *subview in self.view.subviews) { 
     if ([subview isKindOfClass:[UIImageView class]]) { 
      [subview removeFromSuperview]; 
     } 
    } 
} 

- (void)initImageView { 
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picture.jpg"]]; 
    imageView.frame = CGRectInset(self.view.bounds, 100, 100); 
    [self.view addSubview:imageView]; 
} 

@end 

जब मैं "रिकार्ड संदर्भ मायने रखता है" सक्षम के साथ आवंटन साधन के तहत इस भाग गया, मैंने देखा कि प्रत्येक हटा छवि दृश्य destroyImageView दौरान पुनः आवंटित की जाती नहीं किया गया। इसके बजाए, इसे बाद में हटा दिया गया था जब रन लूप -[NSAutoreleasePool release] कहा जाता था।

- (void)destroyImageView { 
    @autoreleasepool { 
     for (UIView *subview in self.view.subviews) { 
      if ([subview isKindOfClass:[UIImageView class]]) { 
       [subview removeFromSuperview]; 
      } 
     } 
    } 
} 

जब मैं इसे फिर से उपकरण के तहत भाग गया, मैंने देखा कि प्रत्येक हटा छवि दृश्य destroyImageView दौरान पुनः आवंटित की जाती किया गया था, @autoreleasepool ब्लॉक के अंत में:

तो मैं अपनी ही autorelease पूल का प्रबंधन करने के destroyImageView बदल दिया है।

+0

इसे समझने के लिए, [ NSAutoreleasePool और Run Loops] (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html) – DanSkeel

9

एआरसी dealloc कोई ऑब्जेक्ट जिस पर कोई और मजबूत संदर्भ नहीं हैं। तो dealloc कुछ करने के लिए, बस nil पर इंगित करने वाले सभी चर सेट करें और सुनिश्चित करें कि ऑब्जेक्ट किसी भी परिपत्र संदर्भ में शामिल नहीं है।

+3

क्या कोई और संदर्भ नहीं होने के तुरंत बाद इसे हटा दिया जाता है, या यह बाद में कुछ समय बाद ही डीलोक करता है? अनुभवजन्य, ऐसा लगता है कि तुरंत होता है, लेकिन क्या इसकी कोई गारंटी है? और यदि नहीं, तो शून्य पर सेटिंग वास्तव में एक dealloc मजबूर नहीं करता है। – prewett

+0

इसे समझने के लिए, [NSAutoreleasePool और Run Loops] के बारे में पढ़ें (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html) – DanSkeel