gpt4 book ai didi

objective-c - 为什么 ARC 会将这个 block 复制到堆中?

转载 作者:太空狗 更新时间:2023-10-30 03:26:10 27 4
gpt4 key购买 nike

考虑这个简单的例子

int i = 42;
int (^aBlock)() = ^ {
return i;
};
NSLog(@"Class: %@", [aBlock class]);

如果没有 ARC,上面的代码打印出来

Class: __NSStackBlock__

而对于 ARC,它会打印

Class: __NSMallocBlock__

我在 _Block_copy 上放置了一个符号断点,看起来 ARC 正在插入一个 Block_Copy() 调用,导致该 block 被移动到堆中

这似乎是一个不必要的开销,而且它首先破坏了在堆栈上放置 block 的全部目的。

这是 ARC 的限制还是设计选择?

最佳答案

block 指针类型被视为 retainable object pointers types根据 documentation,ARC 和此类类型 - 在没有显式所有权限定符的情况下 - 被隐式假定为具有 __strong qualifiers :

If an object is declared with retainable object owner type, but without an explicit ownership qualifier, its type is implicitly adjusted to have __strong qualification.

所以上面的例子等价于

int i = 42;
__strong int (^aBlock)() = ^ {
return i;
};
NSLog(@"Class: %@", [aBlock class]);

documentation还指出:

For __strong objects, the new pointee is first retained; second, the lvalue is loaded with primitive semantics; third, the new pointee is stored into the lvalue with primitive semantics; and finally, the old pointee is released.

later

[...] whenever these semantics call for retaining a value of block-pointer type, it has the effect of a Block_copy [...]

是的,每当将 block 分配给变量时,ARC 都会引入一个 Block_copy 调用,因为该变量被隐式假定为 __strong 限定。

跳过分配将使 block 保留在堆栈中。考虑以下示例:

NSLog(@"Class: %@", [^int{return i;} class]); // => Class: __NSStackBlock__

documentation也告诉我们

The optimizer may remove such copies when it sees that the result is used only as an argument to a call.

确实如此。正如 Catfish_Man 所建议的那样,打开优化(在本例中通过使用 Release 构建配置)将剥离 Block_Copy 调用,将 block 留在堆栈中。

关于objective-c - 为什么 ARC 会将这个 block 复制到堆中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19201405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com