1

我有一个名为 Panel 的类,其中包含这样的弱属性:

@property (nonatomic, weak) 对话框 *container;

在 Instruments 中,我可以看到 setContainer 方法最终调用了 objc_storeStrong。

这个对吗?我认为弱属性不会增加保留计数。

我的初始化方法如下:

- (id) initWithContainer:(Dialog *)pContainer{
    self = [self init];
    if (self) {
        self.container = pContainer;
    }
    return self;
}

请指教。谢谢,

4

3 回答 3

1

Thanks you all for your help while debugging this issue. I greatly appreciate it. My knowledge was/is correct, and weak does not increase the retain count. Unfortunately, I have spent hours debugging this issue that ended up being Instruments picking up an old version of the App that was built without the property being made weak. I don't know how this happened because I was launching instruments from within Xcode project, did a clean, etc... but something was wrong because when I launched instruments it would ask me for the instrument twice, not once, and then instead of launching the app automatically, I would have to start it manually by picking the target (which was wrong, because it usually launches the app automatically.) I resolved the issue by quitting instruments, Xcode and the simulator and restarting again. Thanks!

于 2012-08-04T03:12:37.547 回答
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。

于 2012-08-04T02:55:29.450 回答
0

您应该收到一条objc_storeStrong消息,但不会发送到容器属性。它被发送到您的 arg 是因为局部变量会自动传递强并保留(如果未指定弱),并在分配时保留。当您的方法返回时,arc 会自动为您释放 arg。

于 2012-08-04T02:34:33.923 回答