使用仪器的荣誉。
首先,您应该直接在 init/dealloc 中使用 iVar。
其次,是自己综合,还是自己实现setter?
另外,您是在运行调试代码还是发布优化代码?
现在,解释我为什么用更多问题回答你的问题。
如果你自己合成它(即,声明你自己的实例变量,你还必须将它声明为__weak。如果你让编译器来做它,它会正确处理它。
现在,您显然正在使用 ARC。因此,编译器将自动添加代码来执行手动引用计数(其中一些可能会被优化器稍后删除)。现在,我不会假装自己是编译器自动创建的专家,但它会非常接近以下内容。
以一个基本任务为例...
- (void)setContainer(Container*)container {
_container = container;
}
当编译器完成注入其 ARC 代码时,这将类似于(假设 _container 未声明为 __weak)...
// Converted by ARC -- so it's MRC
- (void)setContainer(Container*)container {
[container retain];
Container *oldContainer = _container;
_container = [container retain];
[oldContainer release];
[container release];
}
现在,让我们更进一步,假设 _container 是 __weak,我们会得到这样的东西......
- (void)setContainer(Container*)container {
[container retain]
Container *oldContainer = [_container retain];
objc_storeWeak(&_container, container);
[oldContainer release];
[container release];
}
现在,objc_storeStrong 是分配给强变量的序列,因此很明显它适合上面的代码。
另外,请注意,编译器在添加代码方面非常明智。优化器非常激进,可以删除大多数明显不需要的保留/释放对。因此,在大多数情况下,您会在函数中看到不同的保留/释放语义,具体取决于您构建的是调试还是发布。
但是,一般来说,您必须期望在任何参数上至少获得一个保留,除非指定为 __unsafe_unretained。