【问题标题】:Is it safe to call Block_copy() and Block_release() on nil?在 nil 上调用 Block_copy() 和 Block_release() 是否安全?
【发布时间】:2013-01-04 00:35:43
【问题描述】:

我需要检查还是它的行为类似于free() 以及它会忽略nil 的地方?

我找不到明确说明一种或另一种方式的文档。

我的怀疑是它是安全的。比如这个……

(lldb) p (void)_Block_release(0)
<no result>

...似乎没有崩溃。我想这就是那个意思?

【问题讨论】:

  • 你是对的,文档没有说明任何内容。
  • 当然,直接调用[... copy][... release] 会更容易——这肯定可以和nil一起使用
  • 这些选择器是否记录在案?
  • @jeffamaphone: clang.llvm.org/docs/… “基金会定义(并提供)块的复制和发布方法。”
  • 很高兴知道。谢谢你的链接。

标签: objective-c memory-management objective-c-blocks null


【解决方案1】:

我试过这个:

Block_copy(-1);

这明显造成了崩溃,于是我单步进入汇编代码:

0x7fff9035342a:  movq   %rdi, %r15
0x7fff9035342d:  xorl   %eax, %eax
0x7fff9035342f:  testq  %r15, %r15
0x7fff90353432:  je     0x7fff903535ca            ; _Block_copy_internal + 430

在 rdi 中应该有唯一的参数被推送:在这种情况下是块地址。

它的内容存储在 r15 中,并在条件跳转之前进行比较。并且地址 0x7fff903535ca 在最后,当它开始从堆栈中弹出时,所以是的,它是 nil 安全的:

0x7fff903535ca:  addq   $8, %rsp
0x7fff903535ce:  popq   %rbx
0x7fff903535cf:  popq   %r12
0x7fff903535d1:  popq   %r13
0x7fff903535d3:  popq   %r14
0x7fff903535d5:  popq   %r15
0x7fff903535d7:  popq   %rbp
0x7fff903535d8:  ret    

【讨论】:

  • 不错的侦探工作。但是,如果它没有记录,它是不安全的。但是,这也可能是一个文档错误,因为现在更改它可能是一个二进制兼容性问题。
【解决方案2】:

我认为它是安全的,例如 free() 等,但找不到任何引用作为证据。

您是否试图避免检查或代码中的混乱?如果是后者,我们可以添加一个宏来实现它,这样我们就不会关心正确的答案是什么......

// Not sure if it's okay to Block_release nil
#define My_Block_release(b) ((b)? _Block_release(b) : 0)

【讨论】:

  • 是的,主要是为了避免混乱。我也考虑了宏观解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 2011-11-06
相关资源
最近更新 更多