web-dev-qa-db-ja.com

「Objective-Cブロックがない」とマークするのに、nilとNULLのどちらが正しいですか。

Objective-Cブロックに何も渡さない場合は、NULLまたはnilのどのキーワードを使用する必要がありますか? Objective-Cブロックは(私が知っているように)Objective-Cオブジェクトですが、関数ポインターとして表されるため、これを質問しています。

NULLnilはどちらも0x0ポインターを示しますが、意味的には異なります。だから私はこれが心配です。

63
Eonil

ブロックは関数ポインタとして表されません。それらはブロックとして表され、これは宣言の^記号で示されます。内部的には、唯一の類似点は呼び出し構文です。そうでなければ、両者は非常に異なります。

それらのメソッドを呼び出すと便利なことがよくあります。たとえば、ガベージコレクションを使用しない場合、後で使用したい場合はneedを使用してブロックでcopyメソッドを呼び出す必要があります。自動保持カウントの出現により、これはブロックをコピーする唯一の方法です。ARCポインタキャストルールにより、Block_copyマクロを使用できなくなるためです。

NULLは、コンパイラに応じて、単に0または(void*)0になります。これは、あらゆる種類のポインターに対して機能します。ただし、Objective-Cの言語規則により、idに直接キャストできないタイプにメッセージを送信しようとすると、警告が表示されます(ARCを使用している場合はエラーが発生します)。 。

メッセージをブロックに送信すると便利な場合があるため、ブロックにはnilを使用する必要があります。


[編集] nilまたはNULLのいずれかを使用すると、まったく同じバイナリコードになることを明確にしましょう。定数の選択は、ブロックをObjective-Cオブジェクトと見なすかどうかに基づいて行う必要があります。これは、独自のretainおよびrelease呼び出しを作成する必要があった時代には大きな問題でしたが、現在はARCがすべてのメモリ管理作業を行っています。

ARCが登場する前にブロックを使用したことがあれば、おそらくそれらはObjective-Cオブジェクトであると思います。そうでない場合、あなたはおそらく彼らがそうであるとは思わない/気づかないでしょう。言語にはまだいくつかのアイデンティティの遺物があります(たとえば、ブロックへの__weakまたは__unsafe_unretainedポインタを持つことができます)が、ほとんどの場合、違いはごくわずかです。 1つを選んで、それに固執してみてください。私は自分のブロックをObjective-Cオブジェクトと考えるのが好きです。

83
zneak