大中央调度的代码块 [英] code blocks with Grand Central Dispatch

查看:77
本文介绍了大中央调度的代码块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ARC编写应用程序,并且想知道以下内容是否会引起问题.具体来说,我正在创建一个对象"A",然后使用GCD将代码块添加到主线程的队列中,并在该代码块中对对象的弱引用执行一些操作.但是,在执行代码块时,我的对象已经为空.由于代码块仅对对象具有弱引用,这会引起问题吗?还是编译器以某种方式知道保留对该对象的引用,因为我的代码块在运行时需要它?

I'm writing an app using ARC, and I'm wondering if the following will cause a problem. Specifically, I'm creating an object 'A', then using GCD I add a code block to the main thread's queue and in the code block I perform some operations on the weak reference to the object. But by the time the code block is executed, my object has already been nullified. Since the code block only has a weak reference to the object, will this cause a problem? Or does the compiler somehow know to keep a reference to the object since my code block needs it when it runs?

    Foo *A = [[Foo alloc] init];

    __weak Foo *weakA = A;

    dispatch_async(dispatch_get_main_queue(), ^{ 

           //...do something here with weakA
    });

    A = nil;

谢谢!

推荐答案

这是一个有趣的问题,有一些细微之处.

This is an interesting question with some subtleties.

您已经明确告诉编译器通过将其标记为__weak来忽略块中的引用,因此该代码不足以使对象保持活动状态,直到执行完该块为止.听起来您已经很清楚了.

You've explicitly told the compiler to disregard the reference from within the block by tagging it as __weak, so this code is not sufficient to keep the object alive until the block has been executed. It sounds like you're clear on that already, though.

通常,当弱引用(例如weakA)被释放时,它会被取消.但是,weakA是一个堆栈变量,因此在块中引用它时,该块会收到其常量化版本,以纪念其在创建块时的值.据推测,weakA的此const副本不能为空.请参阅 Apple文档的本部分有关此内容的更多信息.

Normally, a weak reference such as weakA would be nullified when the object it refers to is deallocated. However, weakA is a stack variable, so when it's referred to in a block, the block receives a const-ified version of it that memorializes its value at the time of the block's creation. Presumably, this const copy of weakA can't be nullified. See this section of the Apple docs for more on this.

如果将weakA的声明更改为

If you change the declaration of weakA to

__block __weak Foo *weakA = A;

然后,弱A被提升到堆栈之外,并且可以从其原始上下文和块中写入.它仍然不会单独保持引用对象的活动,但是在执行该块时,您可以检查其值是否为nil.

then weakA is promoted off the stack and is writable both from its original context and from the block. It still won't keep the referred-to object alive on its own, but at the point of the block's execution you can check to see if its value is nil.

有关__block的更多详细信息,请参见 -跳至"ARC推出新的终身资格预选赛"部分.

More details on __block can be found here - skip down to the section "ARC Introduces New Lifetime Qualifiers".

这篇关于大中央调度的代码块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆