复制与Block_copy()相同吗?

332*_*329 3 objective-c objective-c-blocks

他们是一样的,copyBlock_copy()?怎么样?如果没有,有什么区别?

我好奇这一段时间,所以我决定做一些研究.

看看我发现了我的答案.

332*_*329 5

最后,我找到了答案.copy并且Block_copy()是一样的,但不完全一样.

这是我发现的:


让我们来看看块的类,其中有3个:

  1. __NSGlobalBlock__ - 如果实现一个块而没有任何对块外部的引用,您将获得此类的块.

    void(^block)() = ^{ NSLog(@"GRAZZZZ"); };
    
    Run Code Online (Sandbox Code Playgroud)
  2. __NSStackBlock__- 如果你实现了一个带有一个或多个对块外部的引用的块,你将得到这个类的一个块(当你在非ARC环境中运行时,你会得到这个.在ARC env中,ARC复制它你自动).

    // NON-ARC CODE
    int theOutsider = 1234;
    void(^block)() = ^{ NSLog(@"%d", theOutsider); };
    
    Run Code Online (Sandbox Code Playgroud)
  3. __NSMallocBlock__- 如果复制块,您将获得此类的__NSStackBlock__块.

    int theOutsider = 1234;
    void(^block1)() = [^{ NSLog(@"%d", theOutsider); } copy]; // NON-ARC VERSION
    void(^block2)() = ^{ NSLog(@"%d", theOutsider); }; // ARC VERSION
    
    Run Code Online (Sandbox Code Playgroud)

因为__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)
Run Code Online (Sandbox Code Playgroud)

对于__NSStackBlock____NSMallocBlock__,当你打电话copy给他们时,他们转发到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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

正如您在代码中看到的那样,-[NSBlock copy]会调用_Block_copy!

够了copy,我们来看看吧Block_copy().它定义Block.h如下:

#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
Run Code Online (Sandbox Code Playgroud)

Block_copy()也打电话_Block_copy!!


到目前为止,我可以总结一下,copy并且Block_copy()是一样的!.

希望这可以帮助有同样好奇心的人:D.