【问题标题】:Adding UIImage to NSMutable array for an animation为动画添加图像到 NSMutablearray
【发布时间】:2015-07-20 14:13:47
【问题描述】:

我有一个应用程序,它从存储在我的项目导航器(不是Images.xcassets)的组中的图像创建动画。此代码“有效”,因为它可以正确动画,但使用 imageNamed 会导致内存泄漏,因为图像文件没有被释放。

我不明白为什么用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];

}

我在上面运行了 Instruments,发现我的动画产生了内存泄漏。在 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?

感谢您的阅读。我被难住了,尽管我相信这个问题的解决方案对我来说是一个非常愚蠢的疏忽。证明我是对的;)

【问题讨论】:

  • 我认为可能只是您的路径需要以 [[NSBundle mainBundle] resourcePath] 开头?编辑:啊,没关系,你的变量名误导了:P
  • 愚蠢的问题,但是您使用的是ARC,对吗?您链接的两个问题都是 ARC 之前的问题
  • 我想我正在使用 ARC。我正在运行 Xcode 6.4,部署目标 8.1(当我没有想法时,我尝试了 8.4 的 S 和 G)
  • 第二种方法,你能得到适量的照片吗?还是数组只是空的?如果它是空的,请尝试记录每个图像并查看它是否存在。可能是你使用了错误的资源路径
  • 我明白了!在这里发布答案。它有效,我不知道为什么会这样,但“正确”的方式并不能完成工作。

标签: ios objective-c animation memory-leaks uiimage


【解决方案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];

}

【讨论】:

  • 奇怪的是如何将 .jpg 添加到文件名的末尾使其工作
  • 我在创建本地fileName 变量时尝试了使用和不使用它,然后我在addObject 中尝试了它并偶然发现了它。感谢您的想法和阅读。
猜你喜欢
  • 2014-06-03
  • 2011-10-20
  • 1970-01-01
  • 2015-09-07
  • 2022-12-28
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
相关资源
最近更新 更多