Objective-C
たまに触るので文法くらいは勉強しておく
参考資料:
基本文法
code:クラスの宣言
@interface クラス名 : 親クラス名
{
インスタンス変数宣言
...
}
メソッド宣言
- (戻り値型) メソッド名 : 仮引数リスト ... ; // インスタンスメソッド
+ (戻り値型) メソッド名 : 仮引数リスト ... ; // クラスメソッド(static)
@end
親クラス名は必ず必要になる。
ルートクラス(Javaで言うObject)は処理系によって異なり(!)、GCCであれば Object Cocoa(Mac OS)であればNSObjectを継承してクラスを定義する
親クラスのメソッドを利用する際はsuperを使う(自信を示すselfも使える)
インスタンス変数側には、別途アクセス修飾子を定義するディレクティブ(@から始まる命令)が存在する。
基本的にインスタンス変数はprotectedに、インスタンスメソッドはpublicに固定される
仮引数リストは:区切り
code:クラスの実装
@implementation クラス名
メソッド定義
...
@end
code:クラスのインスタンス生成
int main() {
id obj = Test alloc; // インスタンス生成 allocメソッドがほぼnew演算子の立ち位置 obj method; // インスタンスメソッド呼び出し。ObjCでは、 [オブジェクト メソッド:引数] でメソッド呼び出しになる(!) // ObjCにおいて、メソッド呼び出しは「メッセージ式」とされる
return 0;
}
作成したインスタンスはid型の変数に含められる。(実態はvoid* のような、よろづ型らしい)
code:hello world!
@interface Test : Object
- (void)method;
@end
@implementation Test
- (void)method {
printf("Kitty on your lap\n");
}
@end
int main() {
[Test alloc method]; // (new Test()).method(); みたいな意味 return 0;
}
イニシャライザ(コンストラクタ)
コンストラクタのような機能として、イニシャライザが存在する。ルートクラスで- (id)initが定義されており、これをオーバーライドして利用する。
しかし、[Test alloc] では自動的にinitが実行されず、 [[Test alloc] init] とする必要がある。
が、エイリアスとして + (id)newが定義されているので[Test new]でallocとinitを同時実行してくれる。
メンバ変数の初期値等は、initメソッド内で代入してやる必要がある
メモリ破棄
Objective-CはGCを備えていないので、明示的なメモリ破棄が必要になる
[Test free]で破棄できる。
デストラクタを実装したい場合は、freeメソッドをオーバーライドして実装する。(この際、[super free]を忘れないこと)
プロパティ
うまく飲み込めていない
getter / setterを自動生成する糖衣構文に見える
標準出力
NSLog
NSLog(@"hoge");
@リテラル
何やら色々と機能がある
table:@
NSNumber @12
NSString* @"abc"
NSArray* @[]
NSDictionary @{}
例外処理
code:mm
- (void)test
{
/* 常に実行される */
@try {
NSLog(@"try block");
}
/* 例外が起きると実行される */
@catch (NSException *exception) {
/* 本来の例外処理に投げる (@throwしなければクラッシュされない。@finallyが実行されstrは元の@"01234"の値のまま) */
@throw exception;
}
/* 常に実行される */
@finally {
NSLog(@"*** finally ***");
}
NSLog(@"check"); // 実行されない
}
ラムダ式
参考:
ラムダ式というか、ブロックという概念。rubyっぽい
code:mm
みたいな書き方をする