我有一个名为Panel的类,它包含一个像以下这样的弱属性:
@property(非原子,弱)Dialog *容器;
在Instruments中,我可以看到setContainer方法最终调用了objc_storeStrong。
这是对的吗?我认为弱的属性并没有增加保留计数。
我的init方法如下:
- (id) initWithContainer:(Dialog *)pContainer{
self = [self init];
if (self) {
self.container = pContainer;
}
return self;
}
请指教。 谢谢,
答案 0 :(得分:1)
在调试此问题时,感谢大家的帮助。我非常感谢。我的知识是正确的,弱的不会增加保留计数。不幸的是,我花了几个小时来调试这个问题,结果是仪器拿起了一个旧版本的应用程序,这个版本是在没有财产变弱的情况下构建的。我不知道这是怎么发生的,因为我是从Xcode项目中发射仪器,做了一个干净的等等...但是有些事情是错的,因为当我启动仪器时它会问我两次仪器,而不是一次,然后自动启动应用程序,我将不得不通过选择目标手动启动它(这是错误的,因为它通常会自动启动应用程序。)我通过退出仪器,Xcode和模拟器并再次重新启动来解决问题。谢谢!
答案 1 :(得分:0)
您应该收到objc_storeStrong
消息,但不会发送到容器属性。它被发送到您的arg,因为局部变量会自动强大并保留(如果未指定weak),并保留在赋值中。当你的方法返回时,arc会自动为你释放arg。
答案 2 :(得分:0)
使用乐器的荣誉。
首先,您应该直接在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,否则您必须至少获得任何参数的保留。