它们相同吗, copy
和 Block_copy()
?如何?如果不是,有什么区别?
我对这个好奇了一段时间,所以我决定做一些研究。
看看我找到了什么我的答案。
最佳答案
终于,我找到了答案。 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]
(它的父类(super class))的汇编: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
时,它们会转发到其父类(super class) copy
的 -[NSBlock copy]
方法。这是它在 OS X 10.9 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)
iOS 7.1 SDK 上的汇编代码:
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
和 Block_copy()
是一样的! 。希望这可以帮助和我一样好奇的人:D。
关于objective-c - copy 和 Block_copy() 一样吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24320066/