我使用了这个问题的答案,List selectors for Objective-C object并列出了我的类对象响应的所有选择器。在一个巨大的列表中,我找到了一个名为" .cxx_destruct"的选择器。 (是的,它以点开头),我第一次看到这个,从来没有听说过。我用Google搜索并发现了Objective C: ARC errors (Automatic release problems)。
我脑子里有一些问题吗?
答案 0 :(得分:23)
在ARC之前,开发人员必须刻意编写dealloc
例程,以确保释放对其保留的所有对象的所有引用。这是手动且容易出错的工作。
当引入ARC时,执行等效任务的代码必须在每个拥有除简单属性之外的对象中实现这些手动版本。依赖于手动实现dealloc
例程的开发人员将会失败。
注意:这只是为了在销毁对象时进行引用计数管理。如果您需要删除观察者或执行其他清理工作,那么您仍然需要
dealloc
例程。
结果,使用了来自objective-c ++的预先存在的机制,即一个名为.cxx_destruct
的隐藏选择器,它在被解除分配的对象之前自动调用。 Objective C运行时自动调用此选择器。
对于Objective C ++代码,有一个并行的.cxx_construct
用于构造。
同样,这些是由编译器自动生成的,用于处理ARC上下文中的对象销毁。如果使用和不使用对象属性编译一些简单的目标C代码,您可以看到它正在创建。拿这个示例代码:
#import <Foundation/Foundation.h>
@interface Foo : NSObject
@property (strong) NSObject *anobject;
@end
@implementation Foo
@end
int main()
{
Foo *f = [[Foo alloc] init];
return 0;
}
当我们使用ARC(clang -fobjc-arc test.m -o test -framework foundation
)进行编译并转储类信息时,我们看到.cxx_destruct
选择器,当我们在没有ARC(clang -fnoobjc-arc test.m -o test -framework foundation
)的情况下编译时,我们看不到{{ 1}}选择器。如果您注释掉.cxx_destruct
属性并重新编译,则不会看到NSObject *anobject
,因为它不再需要。