-supportsWeakPointers的角色

问题描述 投票:14回答:2

Apple最近发布了Transitioning to ARC Release Notes,该文档解释了ARC,并解决了将非ARC代码转换为ARC的一些问题。在这些说明的第一个版本中,它们提到以下内容:

如果您[自己]发现必须实现自定义的保留或释放方法,则还必须在您的类中实现以下方法:

-(BOOL)supportsWeakPointers { return NO; }

此方法将防止形成指向您对象的弱指针。强烈建议您找到不需要实现自己的保留和释放方法的解决方案,而不要这样做。

考虑此情况:

  1. 声明一个名为MyClass的类,并实现-supportsWeakPointers返回NO。告诉Xcode使用-fno-objc-arc编译相应的实现文件。为了达到良好的效果,请将类声明为NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE并覆盖-release和-retain。

  2. 在MainMenu.xib中,放置一个MyClass类型的顶级对象。

  3. 在应用程序委托中,为MyClass的实例指定一个弱IBOutlet属性:

    @property (weak) IBOutlet MyClass *myObject;
    

    并将其连接到nib文件中的相应对象。在这种情况下,由于该对象是顶级nib对象,并且File的Owner的类型为NSApplication,that object is created with an extra reference count,这意味着它应保持活动状态,直到出现明确发布。对于ARC,这意味着调用CFRelease(),因为ARC禁止发送释放消息。

我的问题是双重的[[三次:

  1. 为什么-supportsWeakPointers是实例方法而不是类方法?在允许弱引用的情况下,类是否有可能具有不同的实例?
  2. -supportsWeakPointers永远不会发送到加载nib文件时创建的MyClass实例;为什么?我已经通过在其中放置一个NSLog()以及向Xcode添加符号断点的方式对此进行了测试。另外,我永远也不会得到

    cannot form weak reference to instance (0x???) of class MyClass

    运行程序时的消息。
  3. MyClass类型的顶级nib对象在程序执行期间绝不应该被释放,因为我的程序从不释放它。但是,在加载nib文件后,相应的弱输出为nil;为什么?将插座属性更改为强结果会导致对象不同于nil,但这不是必须的。

实际上并不会发生;抱歉。我正在测试的版本分配的是一个未真正使用的新对象,因此ARC将nil正确分配给了该属性。再现此错误的示例项目可用here

我在Mac OS X v10.7.2机器上使用Xcode 4.2和Apple LLVM Compiler 3.0。

objective-c cocoa automatic-ref-counting
2个回答
6
投票
  1. 考虑具有“共享”或“默认”实例以及其他实例(例如NSFileManager)的类的情况。您的共享实例的弱指针行为可能与其他可分配实例不同。有时,不同的实例可能需要不同的弱指针行为。话虽如此,如果是这样的话,可能不太正确。

    ((答案1.为originally written by Chris Parker。我将其添加到约书亚的答案中,以便完成所接受的答案。)

  2. 在您的示例中,将supportsWeakPointers中定义的allowsWeakReference更改为NSObject.h会使事情按预期的方式运行。它被标记为NS_DEPRECATED,但在SDK中似乎还没有其他选择。

3
投票
  1. 考虑具有“共享”或“默认”实例以及其他实例(例如NSFileManager)的类的情况。您的共享实例的弱指针行为可能与其他可分配实例不同。有时,不同的实例可能需要不同的弱指针行为。话虽如此,如果是这样的话,可能不太正确。
  2. Dunno。 :)
  3. 听起来像是个错误;我必须看一个示例项目,以更好地了解正在发生的事情。
© www.soinside.com 2019 - 2024. All rights reserved.