普段、クロスプラットフォームのフレームワークを使っているため、たまにObjective-Cを使う場面でなかなか文法などを思い出せないときがあります。そんなとき、ひとまず読める程度に思い出すために、Objective-C固有の文法などをまとめていっています。
Objective-Cは基本的な文法はC、C++、Javaなどと同じため、それらと異なる部分を抜き出して書いています。また、上記のように他言語を使うことが多く、Objective-Cでがっつり開発することはないため、各々の項目についての詳しい説明は省いています。
ログ出力はNSLogを使います。可変引数をとり、printfなどと同様のフォーマットが使えます。ただし文字列型はたいていNSStringを使うので、%sではなく%@を使います。
NSLog(@"Hello %d %d",10,20);
結果
Hello 10 20
クラス定義は「@interface クラス名:親クラス」とします。
@interface TestClass:NSObject{ // プロパティ定義など } // プロトタイプ宣言など @end
NSObjectは全てのクラスの元となるクラスなので、継承させるべき特定のクラスがないなら、とりあえずこれを継承させておくと便利です。
「@interface」で囲まれている中で定義します。
@interface TestClass:NSObject{ @public int a; @private int b; } @end
「public」「protected」「private」などのアクセス制限が使えます。
「@property」を使うと、先頭に「_」(アンダーバー)がついたプライベート変数が定義され、同時にsetter、getterも定義されます。
@property int a,b;
とすると、
@private int _a, _b;
という変数が自動で定義され、setter、getterも定義されるので、ドット記法でプロパティにアクセスできるようになります。
instance.a = 1 instance.b = instance.a
といった記法が可能になります。 「@property」で「readonly」を指定して読み取り専用変数にしたりも出来ます。 また、よく使われる「atomic/nonatimic」はスレッドセーフかどうかの違いです。 他にstrongは強い参照(参照が他で消されてもデータを保持)、copyはオブジェクトのコピーをとって保持(参照渡しではなく、実体が渡される感じ)します。
「@interface」にプロトタイプ宣言、「@implementation」に実装を書きます。
- (戻り値の型) メソッド名:(型名)引数:(型名)引数:.....
先頭の「-」はインスタンスメソッドを表します。「+」だとクラスメソッドになります。
例えば引数無しなら
@implementation TestClass - (int) getProduct{ return _a * _b; }
引数にラベルを付けるには
- (戻り値の型) メソッド名:(型名)引数 ラベル:(型名)引数 ラベル:.....
とします。
メソッドはprivateとかはないのですが、C言語などと同じでヘッダーファイルにプロトタイプ宣言を書くか、「.m」ファイルに書くかで関数の公開範囲を制限できます。つまり、ヘッダーファイルにプロトタイプ宣言を書かずに「.m」ファイルに
@interface TestClass() - (void) privateMethod; @end
と書いておけば、privateメソッドと同じように使えます。クラス名の後に「()」を忘れないようにしてください。
また、@propertyとかの前にメソッドを定義しようとするとエラーになります。
クラスによって違う事もありますが、インスタンス化はたいてい以下のようにします。
TestClass *tc = [[TestClass alloc] init];
allocがメモリの確保、initがコンストラクタです。
インスタンス変数へのアクセスはCの構造体やC++のインスタンスのように「->」でアクセスできます。
tc->a = 10; tc->b = 20;
プロパティ定義がなされていると、「.」(ドット)でもアクセスできます。
tc.a = 12; tc.b = 3;
メソッドは
[インスタンス変数名 メソッド名:引数 ラベル:引数]
のように呼び出します。 例えば
[tc getProduct] [tc getSum:10 : 12]
のようになります。 これはjavaなどで言えば、
tc.getProduct() tc.getSum(10,12)
に対応する物です。