它们是否相同,copy
和Block_copy()
?怎么样?或者,如果没有,有什么区别?
我对此感到好奇,所以我决定做一些研究。
看看我的答案是什么。
答案 0 :(得分:5)
最后,我找到了答案。 copy
和Block_copy()
相同,但不完全相同。
这是我发现的:
让我们来看看块的类别,其中有3个:
__NSGlobalBlock__
- 如果您实现了一个没有任何对块外部的引用的块,您将获得此类的块。
void(^block)() = ^{ NSLog(@"GRAZZZZ"); };
__NSStackBlock__
- 如果你实现了一个带有一个或多个对块外部的引用的块,你将获得这个类的一个块(当你运行时,你会得到这个块)仅限非ARC 环境。在ARC env中,ARC会自动为您复制)。
// NON-ARC CODE
int theOutsider = 1234;
void(^block)() = ^{ NSLog(@"%d", theOutsider); };
__NSMallocBlock__
- 如果您复制__NSStackBlock__
块,您将获得此类的块。
int theOutsider = 1234;
void(^block1)() = [^{ NSLog(@"%d", theOutsider); } copy]; // NON-ARC VERSION
void(^block2)() = ^{ NSLog(@"%d", theOutsider); }; // ARC VERSION
对于__NSGlobalBlock__
,当您致电copy
时,它什么都不做,只需返回。所以,请忽略它。没有必要移动任何东西堆。下面是-[__NSGlobalBlock copy]
(超级类)的集合:
CoreFoundation`-[__NSGlobalBlock copy]:
0x7fff8bd016f0: pushq %rbp
0x7fff8bd016f1: movq %rsp, %rbp
0x7fff8bd016f4: movq %rdi, %rax
0x7fff8bd016f7: popq %rbp
0x7fff8bd016f8: ret
0x7fff8bd016f9: nopl (%rax)
对于__NSStackBlock__
和__NSMallocBlock__
,当您向他们致电copy
时,他们会转发至其超级copy
的{{1}}方法。这是OS X 10.9 SDK上的汇编代码:
-[NSBlock copy]
iOS 7.1 SDK上的汇编代码:
CoreFoundation`-[NSBlock copy]:
0x7fff8bcc86a0: pushq %rbp
0x7fff8bcc86a1: movq %rsp, %rbp
0x7fff8bcc86a4: pushq %rbx
0x7fff8bcc86a5: pushq %rax
0x7fff8bcc86a6: movq %rdi, %rbx
0x7fff8bcc86a9: callq 0x7fff8be360ac ; symbol stub for: objc_collectingEnabled
0x7fff8bcc86ae: movq %rbx, %rdi
0x7fff8bcc86b1: addq $0x8, %rsp
0x7fff8bcc86b5: testb %al, %al
0x7fff8bcc86b7: je 0x7fff8bcc86c0 ; -[NSBlock copy] + 32
0x7fff8bcc86b9: popq %rbx
0x7fff8bcc86ba: popq %rbp
0x7fff8bcc86bb: jmpq 0x7fff8be361f6 ; symbol stub for: _Block_copy_collectable
0x7fff8bcc86c0: popq %rbx
0x7fff8bcc86c1: popq %rbp
0x7fff8bcc86c2: jmpq 0x7fff8be361f0 ; symbol stub for: _Block_copy
0x7fff8bcc86c7: nopw (%rax,%rax)
正如您在代码中看到的那样,CoreFoundation`-[NSBlock copy]:
0x17949d0: pushl %ebp
0x17949d1: movl %esp, %ebp
0x17949d3: popl %ebp
0x17949d4: jmp 0x18d3d8a ; symbol stub for: _Block_copy
0x17949d9: nopl (%eax)
会调用-[NSBlock copy]
!
_Block_copy
足够了,让我们来看看copy
。它在Block_copy()
中定义为:
Block.h
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
也会调用Block_copy()
!!
到目前为止,我可以总结一下 _Block_copy
和copy
是一样的!。
希望这可以帮助有同样好奇心的人:D。
答案 1 :(得分:0)
当用于块指针类型的表达式时,方法copy
和函数Block_copy()
是相同的。同样,方法release
和函数Block_release()
是相同的。方法copy
和release
只是更多的Objective-C消息传递方式,因为块是Objective-C中的对象,并且使用retain
和release
进行内存管理,就像其他Cocoa一样对象。另一方面,在C / C ++中使用时,只能使用Block_copy()
和Block_release()
来管理块。