2010-11-14 72 views
-1

我有一個奇怪的問題,但我很確定,對你來說不是這樣。如果是這樣,請幫我解釋一下。 我有一個39 UIImages數組將用於動畫UIImageView。並在播放動畫後,內存不會釋放。奇怪的釋放問題

- (void)viewDidLoad { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38]; 

    for (int i=1; i<=39; i++) { 
     NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"]; 
     UIImage *image = [[UIImage alloc]initWithContentsOfFile:path]; 
     [path release]; 
     [actionArray addObject:image]; 
     [image release]; 
     NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    } 
    imageView.animationImages = actionArray; 
    imageView.animationDuration = 4.0; 
    imageView.animationRepeatCount = 1; 
    [imageView startAnimating]; 
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]); 
    [actionArray release]; 
    [pool drain]; 
    [imageView release]; 
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0]; 
    [super viewDidLoad]; 
} 

-(void)playAnimation2{ 
    if ([imageView isAnimating]) { 
     [imageView stopAnimating]; 
    } 
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]); 
} 

沒有發現泄漏,但分配的內存量仍然是24 MB。

或者它不是那麼必要?

編輯:

對不起,我的錯。 由於我的代碼有很多變化,我迷失了它。分析後,我明白了! 非常感謝!

正確的代碼是:

- (void)viewDidLoad { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38]; 

    for (int i=1; i<=39; i++) { 
     NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"]; 
     UIImage *image = [[UIImage alloc]initWithContentsOfFile:path]; 
//  [path release]; 
     [actionArray addObject:image]; 
     [image release]; 
     NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    } 
    imageView.animationImages = actionArray; 
    imageView.animationDuration = 4.0; 
    imageView.animationRepeatCount = 1; 
    [imageView startAnimating]; 
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]); 
    [actionArray release]; 
    [pool drain]; 
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0]; 
    [super viewDidLoad]; 
} 

-(void)playAnimation2{ 
    if ([imageView isAnimating]) { 
     [imageView stopAnimating]; 
    } 
    [imageView removeFromSuperview]; 
    imageView.animationImages = nil; 
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]); 
} 

的問題是與[path release];

+0

-1因爲您的代碼再一次根本不工作。它會立即崩潰,因爲您正在釋放* path *。顯示實際的代碼。編輯:好吧,它不會直接崩潰,但它會*圖像發佈時崩潰。 – Eiko 2010-11-14 17:59:08

+0

我怎樣才能給你整個項目?最有趣的是,沒有任何崩潰。 – 0xDE4E15B 2010-11-14 18:04:47

+0

當然,它不會崩潰,因爲你的圖像不會釋放 - 因此你的問題。 – Eiko 2010-11-14 18:05:29

回答

6

這段代碼有很多錯誤。這完全是一個奇蹟。

第一張:

請勿使用-retainCount。

對象的絕對保留數是沒有意義的。

您應該致電release完全相同的次數導致對象被保留。沒有更少(除非你喜歡泄漏),當然,沒有更多(除非你喜歡崩潰)。

查看Memory Management Guidelines的全部細節。


現在,一些問題:

  • 你問,如果你需要清空數組,然後說:陣列=零; ...不起作用。將數組引用設置爲nil不會對數組執行任何操作;不釋放它或清空它。

  • 你overreleasing path

  • 您加載了一系列圖像,堅持「時間在陣列中,並沒有在該代碼被釋放陣列(或排空)任何東西。您的應用程序會繼續使用內存,並顯示沒有泄漏聽起來像正確的行爲。

  • 你爲什麼要發佈imageView?代碼中沒有任何內容暗示你保留了它,即使它是通過其他機制(IB?)保留的,那將是一個非常奇怪的發佈它的地方。

+0

+1你知道,我可以發誓我以前見過這個完全相同的答案...;) – 2010-11-14 18:50:11

1

我認爲你需要從數組中刪除的所有對象爲它工作。

嘗試從數組中刪除對象,然後嘗試從數組中刪除對象。

+0

試圖array = nil;的ImageView =無;但沒有任何反應。分配的內存仍然是23 MB。有任何想法嗎? – 0xDE4E15B 2010-11-14 17:42:30

1

你正在發佈imageView而沒有保留在任何地方,所以你的代碼可能有其他錯誤。但似乎imageView被另一個對象(最有可能的是超級視圖)保留,它保留在內存中。這也將保持圖像陣列在內存中。

如果您不需要再imageView從父與[imageView removeFromSuperview];

+0

imageView是使用IB創建的。合成並在dealloc中發佈。仍然沒有改善。如果您有空閒時間並希望幫助,我可以通過電子郵件向您發送此代碼。 – 0xDE4E15B 2010-11-14 17:50:54

+0

我明白,但你也在viewDidLoad這裏發佈它,所以你的dealloc可能會崩潰!如果你只是想釋放內存,動畫停止後的'imageView.animationImages = nil;'可能會有所幫助。 – FRotthowe 2010-11-14 17:54:24

+0

dealloc不會崩潰。並且不會在viewDidLoad中釋放相同的結果。也許我錯了 - 刪除imageView和數組後,內存將被釋放?是不是?嘗試imageView.animationImages =零,同樣的結果仍然存在。 – 0xDE4E15B 2010-11-14 17:58:54

1

刪除它正如我們已經在這裏解決:releasing problems

imageView.animationImages = nil;

此外,你需要刪除[path release];或它會崩潰。

Memory Management Guide是一個重要的開始。

編輯從來沒有依賴於retainCount屬性!

編輯2在該方法中釋放imageView顯然也是一個錯誤!

+0

我讀過的指南和我正在做的,正如我認爲的,以正確的方式。奇怪,但沒有與[路徑釋放]崩潰;好的。但爲什麼Allocations Instrument顯示我仍然有24mb使用? – 0xDE4E15B 2010-11-14 18:09:45

+0

男人,你插入imageView.animationImages = nil;給你玩動畫2? – Eiko 2010-11-14 18:11:28

+0

是的,它在那裏,但我不知道發生了什麼,但現在刪除後,它的作品!謝謝 – 0xDE4E15B 2010-11-14 18:15:45