【问题标题】:Objective-C memory leak when returning NSString返回 NSString 时的 Objective-C 内存泄漏
【发布时间】:2015-05-21 10:45:11
【问题描述】:

我想确保我的代码没有泄漏,因为这个小 sn-p 在我的应用程序中被调用了数千次。我通过 Instruments 运行应用程序,而 initWithBytes 似乎有问题。这段代码有什么问题吗?

第一个 [reader readString] 被调用。

case FirstCase:
{       
    NSString *string = [reader readString];
    [self setPropertyByName:propertyName value:string];
    break;
}
...

readString 返回自动释放的字符串。

- (NSString*) readString
 {
       ...
       NSString *string = [[[[NSString alloc] initWithBytes:cursor length:stringLength encoding:NSUTF8StringEncoding] autorelease];         
      return string;
}

代码正常吗?还有其他更好的方法来避免自动释放吗?

我无法将代码更改为 ARC。普通旧的非 ARC 内存管理。

【问题讨论】:

  • 你为什么不用ARC
  • 我同意布莱恩的观点。请帮自己一个忙,阅读 ARC,它是在 iOS 4 中引入的,绝对没有理由不使用它。
  • 请发布完整的readString 方法,最后两行看起来没问题。
  • ARC 将在不久的将来使用。我不能在最后一分钟的补丁中使用它。

标签: ios objective-c iphone memory-management memory-leaks


【解决方案1】:

您发布的内容正常。此时唯一的规则是包含“create”或“alloc”的方法将返回一个需要显式释放的对象。在您的情况下,这是 readString 方法中返回的字符串。

由于对象将被返回,因此您需要将其保留到自动释放池将执行的运行循环周期结束。例如,这意味着如果在for 循环中调用此方法,则在循环退出之前不会释放对象。

如果您想或需要避免这种情况,我建议您使用“create”或“alloc”执行相同的模式并返回未自动释放的对象:

case FirstCase:
{       
    NSString *string = [reader createReadString];
    [self setPropertyByName:propertyName value:string];
    [string release];
    break;
}
...


- (NSString*) createReadString
{
       ...
       NSString *string = [[[NSString alloc] initWithBytes:cursor length:stringLength encoding:NSUTF8StringEncoding];         
      return string;
}

【讨论】:

  • 这样看起来更好。释放前是否需要检查string是否存在?即(if string) [string release];
  • 没有。如果您在 nil 对象上调用任何方法,则不会发生任何事情。所以它已经为你完成了。只是要清楚,如果该方法返回一个值并在 nil 对象上调用,则将返回 0,这可以解释为 nil、NULL、NO、false...
  • 我在问,因为修改代码后收到了“发送到已释放实例的消息”
  • 那么对象已经被释放了。请重新检查对象上的所有释放或自动释放调用。对于调试,您可以使用 retainCount 属性来检查它失败的地方。一旦这个值达到零,对象将被释放。
  • 静态分析后我得到这个:不正确的对象的引用计数递减,此时调用者不拥有
猜你喜欢
  • 2016-09-05
  • 2020-09-15
  • 2015-06-20
  • 2011-03-17
  • 2011-06-07
  • 1970-01-01
  • 2011-10-31
相关资源
最近更新 更多