【问题标题】:When to release UIImage and NSString Resources何时释放 UIImage 和 NSString 资源
【发布时间】:2011-03-31 12:21:39
【问题描述】:

我正在尝试正确进行内存管理,并且在下面的代码中,如果我包含最终的发布声明(用于 filePath 的声明),它会崩溃,我不明白为什么。我已经分配了,为什么不释放呢?

再往下,我将 cellAbout 返回到 TableView。

谁能解释一下?

UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
filePath = [filePath stringByAppendingString:@".png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];
[filePath release];

非常感谢,

克里斯。

【问题讨论】:

  • 一般来说,要找到可能存在内存管理问题的地方,请尝试 xcode 中的“构建和分析”选项。它报告可疑的问题。

标签: iphone objective-c memory-management nsstring uiimage


【解决方案1】:

答案是原来的filePath字符串是分配的,需要释放,但是当你有行时:

  filePath = [filePath stringByAppendingString:@".png"];

您创建了一个不同的字符串 - 指向 filePath 的原始指针现在已经消失并且是泄漏。

这是你真正想要的代码

 NSString *filePath = self.gem.poiType;
 filePath = [filePath stringByAppendingPathExtension:@"png"];
 UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
 imageView.image = image;
 [image release];

所以你不需要释放 filePath - 它是自动释放的。苹果还特别呼吁添加路径扩展。

 NSString *filePath = [self.gem.poiType stringByAppendingPathExtension:@"png"];

实际上是大多数人编写该代码的方式 - 少了一行。

【讨论】:

  • 感谢 Tom、Till、ssteinberg 和 Mike。这一点现在真的很清楚了。泄漏来自 filePath = [filePath... 构造,我不需要释放由 stringByAppending 等创建的任何内容,因为它们是自动释放的。
【解决方案2】:

您的问题

UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];

在这一行之后泄漏文件路径。

filePath = [filePath stringByAppendingString:@".png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];

在这一行之后释放一个自动释放的对象。

[filePath release];

改为

UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
NSString *extendedFilePath = [filePath stringByAppendingString:@".png"];
[filePath release];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: extendedFilePath];
imageView.image = image;
[image release];

【讨论】:

    【解决方案3】:

    [NSString stringByAppendingString] 返回一个新字符串,这就是你泄露旧字符串的地方。

    然后filePath不再归你所有,所以当你稍后释放它时,你会崩溃。

    你可以这样回避整个事情:

    NSString *filePath = [NSString stringWithFormat:@"%@.png",self.gem.poiType];// don't release me.
    

    【讨论】:

      【解决方案4】:

      你在这里泄漏,然后释放一个自动释放的字符串:

      filePath = [filePath stringByAppendingString:@".png"];
      

      如果真的要手动释放,保存指针:

      NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
      NSString *somestring = [filePath stringByAppendingString:@".png"];
      [filePath release];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-12
        • 1970-01-01
        • 2012-01-08
        • 2012-05-04
        • 2013-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多