【问题标题】:Objective-C, ownership and class methodsObjective-C,所有权和类方法
【发布时间】:2012-01-18 19:11:12
【问题描述】:

首先,我是一名 Objective-C 新手。 :)

我了解到,以allocnewcopy 开头的任何内容都会为调用者提供返回对象的所有权。这也适用于类方法吗?我猜它确实,最近我的一个单元测试中的一次崩溃似乎证实了这一点。 Apple 的高级内存管理编程指南没有说明类方法和实例方法之间是否有区别。

更新 我的意思是它也适用于类方法实际上是“逆”。例如,NSDecimalNumber 有一个名为+decimalNumberWithDecimal: 的类方法。它似乎返回了一个自动释放的对象(如果我明确地释放它,那么不久就会发生崩溃)。事后看来,我的问题的答案是显而易见的,因为 Apple 的指南将 newalloc 称为所有权授予方法,它们都是类方法。很抱歉占用了您宝贵的时间。 :)

【问题讨论】:

  • 您的意思是为您生成对象的类方法吗?是的当然。这种模式是 obj-c 中内存管理的关键之一。甚至非苹果框架也适用于这种模式。

标签: objective-c release ownership class-method


【解决方案1】:

是的,这适用于类方法,因为allocnew 是将所有权返回给调用者的类方法。 copymutableCopy 的前缀应该用于返回所有权的实例方法。

编辑更新:

你是正确的,像+decimalNumberWithDecimal: 这样的方法预计会返回一个自动释放的对象,因此没有理由释放它。但是,如果他们决定将方法命名为 +newNumberWithDecimal:,那么您将拥有返回对象的所有权并需要释放它。如果您在方法前加上 new 并返回一个自动释放的对象,Clang 静态分析器实际上会报错。

【讨论】:

【解决方案2】:

还有allocreleaseinit 并不表示所有权,您可能会将其与 alloc 混淆。您可以使用助记符NARC轻松记住它。

如果您将任何类方法命名为initcopyretain,您应该停止。这些方法仅在实例上下文中才有意义。 allocnew 是类方法,只能在该上下文中使用。不要将实例方法命名为 allocnew

该指南之所以没有说它同时适用于实例方法和类方法,是因为所讨论的方法显然是两者的混合,所以显然是这样。

【讨论】:

  • 是的,我把 init 和 new 混在一起了! :)
【解决方案3】:

实际上,这几乎是正确的。 allocnewcopy 为您提供返回对象的所有权。这些是类方法。其他类方法应该返回一个自动释放的对象。实例方法也应该返回一个自动释放的对象。

init 不影响所有权,应与alloc 一起使用,如下所示。

[[SomeCoolClass alloc] init]

new 通常与上述相同,有时被描述为“几乎已弃用”,因为它是对 NeXT 时代的倒退,当时分配和初始化在同一步骤中完成并且无法分开绘制为我们今天使用allocinit

Release 不会影响所有权,但只能用于您已经拥有的对象。否则很可能会发生崩溃。

保留也不会影响所有权,但只能用于您已经拥有的对象。否则,对象可能不会在应该被释放的时候被释放。结果可能是崩溃,但也可能是非常非常奇怪的行为,很难排除故障,因为消息可能会发送到应该已被释放的原始对象,而不是指向同一地址的新对象。

【讨论】:

    猜你喜欢
    • 2011-01-06
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多