コンクリートクラスとかクラスクラスタとか聞き慣れない単語がでてきたので、漠然と理解するよりもちゃんと解説されてるものを読んで理解しておこうと思い調べたのでメモ。
コンクリートクラスって?
コンクリートクラスとは、”有名どころのクラス”のサブクラスで、”有名どころのクラス”を使用しておけば、格納するデータに応じて最適なクラスを自動的に割り当てるObjective-cの機能で呼び出されたクラス。
クラスクラスタって?
クラスクラスタとは、”有名どころのクラス”とそのサブクラス全体を含めたクラス群のこと。
具体的にどういうものかをソースを書いて理解
NSString* str = [[NSString alloc]initWithString:@"/path/path/"]; NSLog(@"str = %@",[str class]);
コンソールには…
2011-12-12 13:41:24.295 playground[13697:f803] str class = __NSCFConstantString
だとさ。
つまり、ユーザが宣言したクラスではなく、そのクラスを継承したサブクラスが自動で割り当てられてて、
ってあれ?パス用のクラスクラスタが割り当てられると思っていたのだけれども?
…。
そうそう、これをさっきのコードに追加してみると…
NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; path = [path stringByAppendingPathComponent:[NSStringstringWithFormat:@"%d.txt",str]]; NSLog(@"path class = %@",[path class]);
こんなレスポンス
2011-12-12 13:41:24.295 playground[13697:f803] str class = __NSCFConstantString 2011-12-12 13:41:24.296 playground[13697:f803] path class = NSPathStore2
となる。
両方ともNSStringで宣言してるのにClassが違う。
ここで実際に表示されたクラス群がコンクリートクラス。
親になってるスーパークラスはNSStringはパブリッククラスと呼ばれる。
なのでNSStringクラスで使用可能なクラスメソッド/インスタンスメソッドは継承してるコンクリートクラスでも使える。
stringByAppendingFormat:メソッドを実行するとNSPathStore2クラスに変換されたりするのかな?という思いつき。
※stringByAppendingFormat:メソッドがNSPathStore2クラスに付属するメソッドなのかどうかは調べてません。
最後にこれを追加してみる。
str = [str stringByAppendingFormat:@"file.txt"]; NSLog(@"str = %@",str); NSLog(@"str class = %@",[str class]);
コンソールには
2011-12-12 13:41:24.295 playground[13697:f803] str class = __NSCFConstantString 2011-12-12 13:41:24.296 playground[13697:f803] path class = NSPathStore2 2011-12-12 13:52:22.455 playground[13873:f803] str = /path/path/file.txt 2011-12-12 13:52:22.456 playground[13873:f803] str class = __NSCFString
最初にチェックしたstrのクラスは”__NSCFConstantString”だったのが”__NSCFString”になってる。
データをstringByAppendingFormat:メソッドによって生成したオブジェクトなので格納されてるデータが変わったのかな?と仮説を立ててみた。
色々試した結果、どうやら格納されるデータをどのように生成したかによって割り当てられるクラスが変動するみたい。
NSString* str2 = [@"test" stringByAppendingPathComponent:@"/path/path/"]; NSLog(@"str class = %@",[str2 class]);
このコードだと、最初に宣言されたstr2は NSStringのstringByAppendingPathComponent:メソッドによって生成されているので、クラスはPathStore2な!と言われて割り当てられた感じ。
2011-12-12 14:12:31.654 playground[14265:f803] str2 class = NSPathStore2
宣言はNSStringで行っているのでメモリサイズもそれに準じたフィールドが宛てられていると推測。なのにクラスが変わっててもいいの?とかとか疑問は湧く、が追い過ぎ注意。
間違っていたら改めるとして、生成時に副次的に生じる情報を元に判別している、とだけ解釈するまでにここでは留めておこう。
図にしてみる
話を戻してコンクリートクラスとパブリッククラスを図にするとこんな感じ。
まとめ
プログラマが宣言するクラスがパブリッククラス。
実際に割り当てられるクラスがコンクリートクラス。
それらを全部合わせてクラスクラスタ。
また一つ、賢くなってしまった…。