yashiganiの英傑になるまで死ねない日記

週末はマスターバイクでハイラルを走り回ります

メソッドがドット記法で呼べる

まずこれを見てほしい

NSArray *a = @[@"hoge", @"fuga"];
NSLog(@"%d", a.count); // 2

なにも驚くことはない.ただのプロパティへのアクセスに見える

では次

NSString *str = NSString.alloc.init;

なにを血迷ったのかバカめ,などと思ったかもしれないが,なんとこのコードはなんの問題もなく動く.動くったら動く

いきさつ(長いので飛ばしてもらっても大丈夫です)

事のはじまりは去年の秋くらい.NSArraycount にドット記法が使えることに気付いた.ちょうど count とかはメッセージ式で呼ぶのがなんか嫌でいい感じにならんのかなーと常々思ってたし,うれしい発見だった.見つけてからは便利に使ってたけど,ふと NSArray のリファレンスなんか穴が空くほど見てるはずなのになんで今まで気づかなかったんだろうと思って見返してみた.けれども,どこにも count がプロパティなんて記載はない.これはどういう仕組みで成り立っているんだ?と思ってちょっと調べてみた

最初はリファレンスにないだけでどうせヘッダにはちゃんとプロパティとして宣言されてるんでしょ,と思って NSArray のヘッダを見てみた.十中八九そうだろうと思ってたけど,残念ながらどこにもそんな記述はなかった

次に,実はドット記法は単なるシンタックスシュガーで,コンパイル時に全てメッセージ式に置き換えられるのではないか,と考えた.しかし,実際プロパティにドット記法でアクセスするときにtypoしてたら Property not Found でエラーになるし,どうやらこの説も間違っていそうだ

皆目検討がつかないので,原点に立ち返って NSArraycount がプロパティなのか調べてみると,このエントリに辿り着いた

どうやら,引数のないメソッドは呼べるらしい

これによると,どうやら引数のないメソッドはドット記法で呼べるらしい.つまり,最初に見つけた NSArraycount はドット記法を使ったプロパティへのアクセスではなくて,ドット記法を使ったメソッド呼び出しだった!しかし,このエントリにはLLVMの拡張らしいけど仕様は見つけられなかったとあり,仕様通りの動作なのかわからなかった.というかほとんどドット記法の是非みたいな内容だった

このドット記法でのメソッド呼び出しだけど,冒頭で例示したようにクラスメソッドでも問答無用で呼べちゃう.覚えておくと,より読みやすいコード書けるようになると思う.けど,仕様なのかどうなのかが全然はっきりしなくて,積極的に使っていいものなのか判断がつかない.問題ないなら積極的に使っていきたい.というか知らなかったから NSArraycount とか NSStringlength で散々使ってる

ということで,これがどういう理屈で動くのか全然わかりません.誰かどういう仕組みなのか知ってる人いたら教えてください!

まとめ

引数のないメソッドは以下のようにドット記法で呼べる

NSString *str = NSString.alloc.init;
NSNotificationCenter *center = NSNotificationCenter.defaultCenter;

覚えておいたらよりリーダブルなコードが書けそう

例にあげといてアレだけど,alloc とか init なんかで使うなよ!絶対だぞ!

仕様なのかどうかよくわからない

どういう仕組みなのか知ってる人,教えてください!

追記

iOS Developers JAPANでドット記法はシンタックスシュガーだよって教えてもらいました.なんでただメッセージ式に置換されてるだけみたいです.件のエントリの人がLLVMの拡張だと言っているのは最近のXcodeでは補完に出てくるそうなので,Clang Completeが賢くなったからなんでしょうね.GCCでも動作はするみたいです!