- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
-(id)getBlockArray
{
int val = 10;
return [[NSArray alloc] initWithObjects:^{NSLog(@"1-%d",val);},^{NSLog(@"2-%d",val);} ,^{NSLog(@"3-");}, nil];
}
最佳答案
不捕获任何变量的 block 是全局 block 。由于 block 的所有实例都是相同的,编译器可以在程序的生命周期内静态分配一个副本。
捕获变量(闭包)的 block 是堆栈或堆(malloc) block 。 block 从堆栈开始,作为堆栈 block 。当第一次复制堆栈 block 时,它被移动到堆中。复制堆 block 不会创建另一个副本;但只是保留它。
第三个是全局 block 是显而易见的,因为它不捕获任何变量。前两个捕获变量。显然,第一个是复制的,第二个不是。
ARC 规范不保证前两个 block 中的任何一个都被复制。但是,如果需要,ARC 编译器可以插入额外的副本。 (复制一个 block 不会有什么坏处。)
我相信当前版本的 Clang ARC 编译器在将 block 指针类型的表达式传递给非 block 对象指针类型的参数时会保守地插入副本。这是一个好主意,因为采用非 block 对象指针的 API 通常只在需要存储它们时才保留它们,而不是在 block 需要时进行复制。事先复制它们可以防止这种情况下的不安全。这解释了第一个参数的复制。第二个呢?我的猜测是,这是因为它是可变参数而不是显式参数(-[NSArray initWithObjects:]
采用一个类型为 id
的参数,然后具有可变参数,.. .
),而 Clang 关于传递时复制的规则可能不适用于可变参数(因为它不知道“参数类型”)。
在将 block 传递给采用普通对象指针并存储它们的 API 之前,您应该始终复制 block ,例如 -[NSArray initWithObjects:]
,因为无法保证复制。
关于ios - 在 Arc 中,Block 在什么情况下是 __NSMallocBlock__ 或 __NSStackBlock__ 或 __NSGlobalBlock__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29138936/
如果我的 block 不捕获变量,我会得到 __NSGlobalBlock__。 Class class = [^{ } class]; NSLog(@"%@", NSStringFromClass(
-(id)getBlockArray { int val = 10; return [[NSArray alloc] initWithObjects:^{NSLog(@"1-%d",
我是一名优秀的程序员,十分优秀!