まず、いくつかのコンテキスト: SO に関する質問に答えているときに、著者が に似た構文でゲッターを設定しようとしていた投稿に出くわしました[self.propertyGetter:newValue];
。なんらかの理由でこれがコンパイルされ、「これは nil の呼び出しになるのではないか?」と思いました。それで、私の質問は、なぜこれが「うまくいく」のですか?(完全に明確にするために、ポスターはこれが効果がないと不平を言っていたので、「作業」とはコンパイルを意味します)。
2 に答える
引用したコードは[self.propertyGetter:newValue]
. 以下は、Objective-C コンパイラがこれを解析する方法です。
左括弧の後の最初のものは、メッセージの受信者でなければなりません。そのコードでは、受信者は の値ですself.propertyGetter
。コンパイラは に変換self.propertyGetter
し[self propertyGetter]
ます。したがって、引用したコードを として書き直すことができます[[self propertyGetter]:newValue]
。
ここで、コンパイラはメッセージのセレクターを把握する必要があります。setStatusBarHidden:animated:
通常、一連のキーワードの後にコロンが続く のようなキーワード セレクターが表示されます。しかし、キーワードの長さがゼロになる可能性があることがわかりました。したがって、コロン自体は有効なキーワード セレクターです。したがって、コンパイラは次のように認識します[[self propertyGetter] :newValue]
。(長さゼロのキーワードを使用することは、ほとんどの場合非常に悪いスタイルです。)
そのセレクターを使用してインスタンス メソッドを宣言できます。例えば:
- (void):(NSObject *)newValue;
[self propertyGetter]
そのメソッドを持つクラスのオブジェクトを返す場合、コードはコンパイルおよび実行されます。
コンパイラーがそのような名前のメソッドを持つクラスを検出し、[self propertyGetter]
type を返すid
場合、コードはコンパイルされます (はワイルドカード型であり、既知のメッセージ セレクターid
を送信しようとしてもコンパイラーは文句を言いません) 。[self propertyGetter]
ただし、実際にメッセージを理解していない場合、アプリは実行時にクラッシュし:
ます。
すべての Objective-C オブジェクトはデフォルトで動的エンティティであるため、これはコンパイルされます。コンパイルはできますが、実行時にクラッシュします。
ソース。