2015-07-20 44 views
3

我有一個應用程序,從我的項目導航器(不是Images.xcassets)中的組中存儲的圖像創建動畫。此代碼「起作用」,因爲它的動畫效果不錯,但使用imageNamed會導致內存泄漏,因爲圖像文件沒有被釋放。添加UIImage到動畫的NSMutable陣列

我不明白爲什麼添加imageNamed:工程添加圖像到我的陣列,但imageWithContentsOfFile:沒有。

一個在我的應用程序的力學一點信息:

self.myPhoto設置從另一個ViewController的SEGUE。圖像的數量可能會有所不同,因此在將其添加到陣列之前,我會測試以查看文件是否「存在」。

文件名遵循這個命名約定:

"1-1.jpg" 
"2-1.jpg" 
"2-2.jpg" 
"99-1.jpg" 
"99-2.jpg" 
"99-3.jpg" 
"99-4.jpg" 

此代碼的工作,但圖像不解除分配,從而導致內存泄漏:

- (void)startAnimation { 

    NSMutableArray *imageArray = [[NSMutableArray alloc] init]; 

    for (int imageNumber = 1; self.myPhoto != nil; imageNumber++) { 
     NSString *fileName = [NSString stringWithFormat:@"%@-%d.jpg", self.myPhoto, imageNumber]; 

     // check if a file exists 
     if ([UIImage imageNamed:fileName]) { 
      // if it exists, add it to the array 
      [imageArray addObject:[UIImage imageNamed:fileName]]; 
     } else { 
      // otherwise, don't add image to the array 
      break; 
     } 
    } 

    self.myImageView.animationImages = imageArray; 
    self.myImageView.animationDuration = 1.5f; 
    self.myImageView.animationRepeatCount = 0; 
    self.myImageView.contentMode = UIViewContentModeScaleAspectFit; 
    [self.myImageView startAnimating]; 

} 

我跑了儀器就可以了,看見我了從我的動畫中產生內存泄漏。在StackOverflow上稍微挖掘一下,我發現我將文件添加到myArray的方式導致圖像沒有被釋放。

所以我想這一點,而不是:

- (void)startAnimation { 

    NSMutableArray *imageArray = [[NSMutableArray alloc] init]; 

    for (int imageNumber = 1; self.myPhoto != nil; imageNumber++) { 
     NSString *fileName = [NSString stringWithFormat:@"%@-%d", self.myPhoto, imageNumber]; 

     // check if a file exists 
     if ([UIImage imageNamed:fileName]) { 
      // if it exists, add it to the array 
      [imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"%@", fileName] ofType:@"jpg"]]]; 
      NSLog(@"%@ added to imageArray", fileName); 
     } else { 
      // otherwise, don't add image to the array 
      break; 
     } 
    } 

    NSLog(@"There are %lu images in imageArray", (unsigned long)imageArray.count); 

    self.myImageView.animationImages = imageArray; 
    self.myImageView.animationDuration = 1.5f; 
    self.myImageView.animationRepeatCount = 0; 
    self.myImageView.contentMode = UIViewContentModeScaleAspectFit; 
    [self.myImageView startAnimating]; 

} 

當我做這種方式,其中動畫負荷出現在頁面上,但圖像沒有被添加到我的陣列 - 的。這是一個記錄完備的問題。這裏有覆蓋這個問題的幾個帖子:

Dirty Memory because of CoreAnimation and CG image

How do I use imageWithContentsOfFile for an array of images used in an animation?

謝謝您的閱讀。我很難過,但我相信解決這個問題對我來說是一個非常愚蠢的疏忽。證明我是對的;)

+1

我認爲這可能只是你的路徑需要有[一個NSBundle mainBundle] resourcePath]開頭?編輯:啊,沒關係,誤導你的變量的名稱:P –

+1

愚蠢的問題,但你使用ARC,對吧?這兩個問題你都聯繫在一起ARC –

+0

我想我正在使用ARC。我正在運行Xcode 6.4,部署目標8.1(當我用完想法時嘗試了8.4的S和G) – Adrian

回答

1

我做了一些小小的改變,因爲無奈之下,我偶然發現了「答案」。評論請注意,我所做的更改:

- (void)startAnimation { 

    NSMutableArray *imageArray = [[NSMutableArray alloc] init]; 

    for (int imageNumber = 1; self.myPhoto != nil; imageNumber++) { 
     // I set the filename here, adding .jpg to it 
     NSString *fileName = [NSString stringWithFormat:@"%@-%d.jpg", self.myPhoto, imageNumber]; 

     // check if a file exists 
     if ([UIImage imageNamed:fileName]) { 
      // if it exists, add it to the array 
      // I blanked out ofType, as it's set when I create the local fileName variable 
      [imageArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"%@", fileName] ofType:@""]]]; 
     } else { 
      // otherwise, don't add image to the array 
      break; 
     } 
    } 

    self.myImageView.animationImages = imageArray; 
    self.myImageView.animationDuration = 1.5f; 
    self.myImageView.animationRepeatCount = 0; 
    self.myImageView.contentMode = UIViewContentModeScaleAspectFit; 
    [self.myImageView startAnimating]; 

} 
+0

奇怪的是,如何將.jpg添加到文件名的末尾使其起作用 –

+0

我嘗試了使用和不使用當我創建本地'fileName'變量時,然後在'addObject'中嘗試了它並偶然發現它。感謝您的想法和閱讀。 – Adrian