何时在带有ARC的对象引用上使用__block关键字

32 浏览
0 Comments

何时在带有ARC的对象引用上使用__block关键字

这个问题已经有了答案:

“ __block”关键字是什么意思?

我理解对于标量变量,__block存储类型在块看到它们的更新时是必需的,但是,对象什么时候需要它?我相信,当捕获一个self引用供块内使用时应该使用__weak,但我不知道何时需要实际使用__block存储类型来处理普通对象。

admin 更改状态以发布 2023年5月21日
0
0 Comments

它们用于函数级别的变量。这些变量在块内(和封闭范围内)是可变的,并且在任何引用块复制到堆时都会被保留。通过__block存储修饰符声明的封闭词汇作用域内的变量是通过引用提供的,因此可变。任何更改都会反映在封闭词汇作用域中,包括在同一封闭词汇作用域内定义的任何其他块中。

__block变量存储在与变量的词汇作用域以及在变量的词汇作用域中声明或创建的所有块及块副本之间共享的存储器中。因此,如果块的任何副本在帧结束后存活(例如通过某个地方排队以供稍后执行),则存储器将存活。因此,在需要在块内修改对象或在堆栈帧的破坏之后需要该对象的情况下使用它们。

0
0 Comments

如果你想要通过块内部的代码改变标量变量的值,那么__block是必需的。捕获的标量在块内看起来像是const,因此不能被改变。如果你有一个对象的指针,同样的规则适用 - 捕获的指针本身将是一个const指针,因此不能被修改,但是它所指向的对象可以被块内部的代码修改。如果你想改变所指向的对象,则指针本身必须改变,因此该指针必须用__block类型声明。永远不需要将对象本身声明为__block,只需要将指向该对象的指针声明为__block,并且仅在指针必须被更改时才需要声明。\n\n如果你有正确的心理模型,块就不那么混乱了。重要的是要知道,块最初分配在堆栈上,因此在堆栈帧弹出时,词法作用域被销毁,块也会消失。如果你希望块在创建它的词法作用域的生命周期之外活得更久,可使用Block_copy()或发送它一个-copy消息将其移动到堆中。当块被复制到堆中时,所有捕获的const变量都跟着它来了,并且这些const变量指向的任何对象都会被保留下来。当块从堆中移除时,被const变量所指向的所有对象都将被释放。\n\n__block变量在编译时“内部”有一个额外的间接层(你看不到),包含在块中,因此当块被复制到堆中时,捕获的__block变量和这些不可见的指针也会被调整为指向这些__block变量在堆中的新位置。这意味着__block变量的地址可能会改变,因此如果你使用该地址,请小心。你也可以看到__block变量在某种意义上“在”块的外部生存,因此这些变量可以从块外部的代码中读取和修改。\n\n我简要地提到了这些,但你可以在以下链接中找到更好的解释,它们按复杂性递增排列:\n\nhttp://ios-blog.co.uk/tutorials/programming-with-blocks-an-overview/\n\nhttp://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html\n\nhttp://www.mikeash.com/pyblog/friday-qa-2011-06-03-objective-c-blocks-vs-c0x-lambdas-fight.html

0