消息传递__weak对象?(Messaging a __weak object?)

2019-08-17 02:51发布

如果我将消息发送到一个微弱的对象会发生什么? 是否发送消息拥有的对象,并保持在内存中,直到回报?

我想这个模式:

__weak MyObject *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf doSomeAction];
});

假设weakSelf是当发送的消息,可能它,而被释放非空doSomeAction是工作还是它保证仍然有效,直到doSomeAction回报?

Answer 1:

从锵ARC文件 :

执行上的对象的左值一个左值到右值转换时,会发生

  • 对于__weak对象,当前的指针对象被保持并且然后在当前满表达的端部释放。 这必须相对于分配和指针对象的最终发布原子执行。

消息传递弱引用执行左值到右值转换对可变的,这意味着弱引用的值将被保留,然后在当前满表达(基本上,语句)的端部释放。 它基本上相当于分配到一个强大的变量,其范围仅持续当前语句,然后短信,强有力的变量。

这里的重点是:如果你想留言弱变一次,再也不会去碰它,你不关心的参数来评估的情况下该方法的副作用,其中弱引用结束了nil ,则继续前进,直接消息弱引用。 但是,如果你需要参考弱引用两次(在不同的语句),或评估的参数做的事的副作用,那么你应该分配给一个变量强和测试用于非nil出发之前。



Answer 2:

您询问:

假设weakSelf是不nil时,发送的消息,而这可能会被释放doSomeAction是工作还是它保证仍然有效,直到doSomeAction回报?

是的,它不仅保持有效,直到doSomeAction返回时,它会保留该块的其余部分了。 考虑以下:

- (void)dealloc
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)startBackgroundOperation
{
    __weak MyObject * weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [weakSelf doSomeAction];
        sleep(5);
        [weakSelf doSomeAction2];
    });

    sleep(1);
}

- (void)doSomeAction
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)doSomeAction2
{
    NSLog(@"%s", __FUNCTION__);
}

在这个例子中,我确保对象在范围上的块启动时,却可以让它掉下来的之间范围doSomeActiondoSomeAction2 ,但块似乎保留它的块完成。 但是,如果我注释掉的调用doSomeAction中, weak引用是nil通过它到达的时间doSomeAction2 ,正如你所期望的。


顺便说一句,在2011 WWDC - #322 - Objective-C的进步深入 ,他们指出(约27:00分钟到视频),他们指出,如果你提领weakSelf ,你应该有一个局部强调度块内引用,以保护自己的竞争条件,即:

__weak MyClass *weakSelf = self;

dispatch_async(dispatch_get_main_queue(), ^{
    MyClass *strongSelf = weakSelf;
    if (strongSelf)
        [strongSelf->myView doSomeViewAction];
});

这将保持它的块的持续时间(假设它尚未由执行该块的时间释放)。



文章来源: Messaging a __weak object?