它们相同吗, copyBlock_copy() ?如何?如果不是,有什么区别?

我对这个好奇了一段时间,所以我决定做一些研究。

看看我找到了什么我的答案。

最佳答案

终于,我找到了答案。 copyBlock_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 !!

    至此,我可以总结一下, copyBlock_copy() 是一样的!

    希望这可以帮助和我一样好奇的人:D。

    关于objective-c - copy 和 Block_copy() 一样吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24320066/

    10-10 14:20