チェックする必要がありますか、それともfree()
無視されるような動作をしnil
ますか?
いずれかの方法で明確に記載されているドキュメントを見つけることができません。
私の疑いはそれが安全だということです。例:これ...
(lldb) p (void)_Block_release(0)
<no result>
...クラッシュしなかったようです。それが意味することだと思いますか?
チェックする必要がありますか、それともfree()
無視されるような動作をしnil
ますか?
いずれかの方法で明確に記載されているドキュメントを見つけることができません。
私の疑いはそれが安全だということです。例:これ...
(lldb) p (void)_Block_release(0)
<no result>
...クラッシュしなかったようです。それが意味することだと思いますか?
私はこれを試しました:
Block_copy(-1);
これは明らかにクラッシュを引き起こしたので、私はアセンブリコードに足を踏み入れました:
0x7fff9035342a: movq %rdi, %r15
0x7fff9035342d: xorl %eax, %eax
0x7fff9035342f: testq %r15, %r15
0x7fff90353432: je 0x7fff903535ca ; _Block_copy_internal + 430
rdiでは、プッシュされる引数は1つだけである必要があります。この場合は、ブロックアドレスです。
その内容はr15に保存され、条件付きジャンプの前に比較されています。そして、アドレス0x7fff903535caは、スタックからポップし始めたときに最後にあるので、はい、安全ではありません。
0x7fff903535ca: addq $8, %rsp
0x7fff903535ce: popq %rbx
0x7fff903535cf: popq %r12
0x7fff903535d1: popq %r13
0x7fff903535d3: popq %r14
0x7fff903535d5: popq %r15
0x7fff903535d7: popq %rbp
0x7fff903535d8: ret
free()などのように安全だと思いますが、証拠としての引用は見つかりませんでした。
コードのチェックや混乱を避けようとしていますか?後者の場合、それを作成するマクロを追加して、正しい答えが何であるかを気にしないようにすることができます...
// Not sure if it's okay to Block_release nil
#define My_Block_release(b) ((b)? _Block_release(b) : 0)