2011-06-25 2 views
26

私が見てきたコードは次のように:Objective-C:respondsToSelector :?の前にnilをチェックするのはなぜですか?

if (delegate != nil && [delegate respondsToSelector:@selector(doSomething)]) ... 

しかし、nilにメッセージを送信するだけで(NOに評価される)nilを返し、なぜだけでない。

if ([delegate respondsToSelector:@selector(doSomething)]) ... 

が速く元ですif delegate == nil?いずれにしても、後者のほうがコードが少ないからです。

lessは、moreより優れています。すべてのUnixプロがそれを知っています。

+0

私は後者のものを使用する傾向があります。また、不要なnilチェックのコードをスキャンする傾向があります。 nilが傷ついていない場合は、チェックしないでください。もしnilがプログラミングミスであれば、それをチェックしないでください(代わりにアサーションを使用してください)。 – Eiko

答えて

22

objc_msgSend Objective-Cで動的メッセージを送信するために使用される関数は、最初の引数(メッセージ受信者)をただちにチェックし、それが== nilであれば返します。したがって、nilメッセージの唯一のオーバーヘッドは、動的にリンクされたライブラリ関数呼び出しです。これは、「バイナリ内」関数呼び出しよりもわずかに高価です。全体的に、あるアプローチは他のアプローチより効率的ですか?コンパウンドの条件文は、通常、追加の分岐を必要とするため、コンパイラが生成するコードを見ることなく答えを決定することはできませんが、実行中のプログラムをプロファイリングすることが重要です。時期尚早な最適化はBad Thing™ですが、実際に効率を検討し、このような「イディオム」に疑問を呈したことをお祝いします。

+0

ハハ。甘い答え!ありがとう! – ma11hew28

+0

@MattDiPasquale彼の答えを拾ってください〜 – user392412

+0

誰かが2つの異なるバージョンをコンパイルし、生成されたアセンブリを分析してどちらが速いのかを調べると面白いでしょう。 :) – ma11hew28

5

あなたは正しいですか? nilに送信されたメッセージは自動的にnilを返すため、これはObj-Cの技術的に不要なオーバーヘッドです。ただし、最初にnilかどうかを確認してrespondsToSelector:への呼び出しを無視すると、respondsToSelector:コールのオーバーヘッドはスキップされます。だからそれは速くなるだろうが、どれくらいの分、わからない。

-3

構文上の問題があります。-respondsToSelectorをnilオブジェクトに送信すると、常にnilが返されます。これがあなたがそのようなことをする理由です。

関連する問題