今更ながら、クイックルックアプリとか書きたくなってObjective-Cを覚えている。
オブジェクトについて使い方を詰まったサンプルコードを書いておいた
変数
変数は、宣言=>初期化=>代入の3ステップ
変数宣言短縮形
NSString *str = @"Hello World"; char*cp = "Hello World";
文字の場合とくに、変数宣言&初期化&代入はC言語っぽいスタイルになるように工夫されている。
int/uint や char も使えるので、使ってどうぞ。
変数の出力
コンソールに出力するときは、 NSLog や printf を最初に覚えるとイイ
printf("%s", [@"あああ" UTF8String ] ); NSLog(@"あああ");
@マークは重要
@マークはObjective-C特有の機能を表現するために、ソースコードで頻繁に使う。
オブジェクトの定義
「クラスの宣言」「クラスの実装」を分ける。C言語で「関数の宣言」と「関数の実装」が分けられるのと同じ。
定番のAnimalクラスを実装する
Animalクラスを作る。コンストラクタの引数で鳴き声を与えるものを作ります。
クラスの宣言
@interface Animal : NSObject (略 @end
クラスの実装
クラス変数や実体の定義は別に書く。このへんはC++も同じだね。
@implementation Animal (略 @end
- @interface 〜@end :クラス定義
- @implementation 〜@end :クラス実装
インスタンスメソッド:実装
メソッドの実装も同じ
@implementation Animal - (void) bark{ NSString *a = self.voice; const char *cp = [a UTF8String]; printf("「%s」\n", cp); } @end
実装の各ファイル
実装を Animal.m 定義をAnimal.h に書くのが一般ルール。
もちろん同一ファイルに書いても動く
このへんはコンパイラに渡す設定次第なので、何とでも。ファイルにベタ書きしたって構わない。
コンストラクタでインスタンス生成
NSObjectを継承したインスタンスを生成をするのもの、C言語と同じ手続きですね。
変数の仕様を宣言して、メモリを確保して、オブジェクトをコピーする。
Animal *a; //変数名を宣言 a = [Animal alloc]; //変数初期化 a = [a init]; //インスタンス生成
これらの手続きは、ひとまとめにできる。
Animal *a = [ [Animal alloc] init];
ひとまねに書くことが出来る。alloc や init は状況によって変わる。
alloc/initでnew 同等とするのは褒められた説明じゃない。
コンストラクタ関数を定義する。
[super init] をして、return self すれば、init の代替になれる。オーバーライドも出来る。
@implementation Animal (略 - ( id ) init { self = [ super init ]; self.name=@"未確認生物"; self.voice=@"□□□□□□"; return self; } (略 @end
return self する感じで動くようだ。
ループ for in
forEach 相当な for in がある。 while / for はC言語と同じ。
for( id e in animals ) { printf( "%s" , [[e info ] UTF8String] ); [e bark]; }
for in ループは id で全て受けられる。 id はObjective-Cのオブジェクトそのものを指す。
定義済み変数に入れるならキャストする。
キャスト
idに入れたらキャストして使う。
for( id key in dict ) { NSString *str = (NSString *) key; }
配列
配列はC言語スタイルのものと、NSArrayベースな物がある。
シンタックスシュガーや新しい書き方が定義されていて、そのほうが便利なので、それだけ覚えれればイイ
可変長配列
NSMutableArrayを可変長で使います。
NSMutableArray *animals = [ [ NSMutableArray alloc ] init];
可変長配列は通常クラスと同等に配列。
連想配列(ディクショナリ)
ディクショナリでハッシュマップを作れます。
NSDictionary*dict = @ { @"ドッグ" : @"わんわん", @"キャット" : @"にゃーん", @"ピジョン" : @"くるっぽー", @"ピッグ" : @"ぶひぶひー", };
初期化で代入時に、@{} のシンタックスシュガーを使うのが楽です。
[foo bar ] 形式と foo.bar 形式
Animal *a = [ [ Animal alloc ] init ]; [a bark];
Animal *a = [[ Animal alloc ] init ];
a.bark;//[a bark]の代替でプロパティへのアクセスと同等にメソッドを呼べる。
id で変数を一括で受けても大丈夫
id 型がすべてのオブジェクトの参照先に使える。したがって id を使って変数宣言してもイイ。
id a = [ [ Animal alloc ] init ]; [a bark]; a.bark; //ドットアクセスはコンパイル時に型チェックエラー
*1:できるのかな?ちゃんと調べてない