【问题标题】:Objective-C Returning Autoreleased CopiesObjective-C 返回自动发布的副本
【发布时间】:2012-06-25 21:29:39
【问题描述】:

我在尝试了解 Apple 的内存管理标准时遇到了一个奇怪的问题。假设我有一个方法可以返回一个副本而不让用户知道它是一个副本。

+(Point2D*) Add:(Point2D*)a To:(Point2D*)b
{
        Point2D * newPoint = [a copy];
        [newPoint Add:b]; // Actually perform the arithmetic.
        return [newPoint autorelease];
}

问题是Xcode 的Analyze 函数将此标记为发送了太多-autorelease 调用的对象。我假设这是因为 -copy 隐含地假设您正在取得所有权,因此 +0 保留计数的可能性很可能。但我不完全确定。

Xcode 的分析信息

+(Point2D*) Add:(Point2D*)a To:(Point2D*)b
{
        Point2D * newPoint = [a copy]; // <- 1. Method returns an Objective-C object with a +0 retain count.
        [newPoint Add:b];
        return [newPoint autorelease]; // <- 2. Object sent -autorelease method.
                                       // <- 3. Object returned to caller with a +0 retain count.
                                       // <- 4. Object over -autoreleased: object was sent -autorelease but the object has zero (locally visible) retain counts.
}

关于为什么会发生这种情况的任何提示或提示?除非我遗漏了什么,否则代码应该可以正常工作,因为自动释放直到安全时间才会触发(即它的工作方式有点像便利构造函数,用户有时间保留。)

根据要求,-copyWithZone: 将按如下方式实现:

-(id)copyWithZone:(NSZone *)zone
{
        return [[Point2D allocWithZone:zone] initX:x Y:y Z:z];
}

【问题讨论】:

  • 您的代码看起来不错。您应该自动发布副本。你使用的是什么版本的 Xcode?在我的身上,我什至无法命名一种名为“Point”的类型,因为它与 QuickTime 中的类型冲突:developer.apple.com/library/mac/#documentation/QuickTime/…
  • 你说的没错,我用了一个一般的case,简单的给Point随便取了个名字。在我的代码中,它出现在我的 Matrix3x3、Matrix4x4、Vector3、Vector4 类中。出于这个问题的目的,我试图引用一个一般案例。 - 我已编辑问题以使用 Point2D 以避免进一步混淆。另外,我正在使用 Xcode 4.2 Build: 4C199
  • 这一定是你的 Xcode 中的一个错误。试试 Xcode 4.3
  • 谢谢,我假设这是一个错误。不幸的是,我无法做更多的测试,因为我正在运行 Snow Leopard 并且无法升级到 4.3 - :/ 但事实上我一直听到这是我应该做的并且看到其他几个例子就足够了.如果有人可以确认代码在 4.3 上没有正确分析,我会很乐意将其标记为完整。谢谢!

标签: objective-c memory-management copy autorelease


【解决方案1】:

在您的Point 类中正确实现-copyWithZone:(NSZone*)zone(或至少请在此处复制)

【讨论】:

  • 我已编辑原始帖子以包含 -copyWithZone:,感谢您的快速回复! - 注意:这并不能解决分析问题,因为我已经实现了 -copyWithZone:。 :(
  • 啊,看:“copyWithZone: 方法的子类版本应该首先向 super 发送消息,以合并其实现,除非子类直接来自 NSObject。” (c) 来自 Apple 的 NSObject 类参考。尝试正确实现 copyWithZone。
  • developer.apple.com/library/mac/#samplecode/… 下载此示例代码并尝试查看 copyWithZone 实现(来自 NSObject 的 SKTGraphic 和来自 SKTGraphic 的 SKTImage)
  • 即使更改后,它仍然被分析为可能的内存问题。我认为这可能是我的 XCode 版本的问题,但我无法升级,因为我使用的是 Snow Leopard。 :/ 不过不错,我会从现在开始正确实施 copyWithZone:。 (其实我并没有意识到这个问题。)
猜你喜欢
  • 1970-01-01
  • 2010-11-16
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
相关资源
最近更新 更多