Objective-C
- Objective-C は、C 言語の拡張セット
Objective-C プログラミング言語:Objective-C 言語
- オブジェクト識別子は id という明確なデータ型として定められています。
- この型はオブジェクトへのポインタとして定義されています。
- 実際には、オブジェクトのインスタンス変数、つまりオブジェクトに一意のデータへのポインタです。
- オブジェクトはアドレスで識別されます。
- デフォルトのデータ型(intに代わって)
- オブジェクトは実行時に動的に型定義されます。
- 動的型定義は、後述する動的バインディングの基礎となります。
id anObject;
- オブジェクトに何かを実行させるには、メソッドの適用を指示するメッセージをオブジェクトに送信します。
- Objective-C では、メッセージ式を大括弧で囲みます。
[myRect display]; [myRect setOrigin:30.0:50.0]; [myRect setWidth:10.0 height:15.0]; [receiver makeGroup:group, memberOne, memberTwo, memberThree];
- myRect を塗りつぶした長方形として描画する場合は isFilled 変数を YES に、輪郭だけを描画する場合は NO に設定します。
BOOL isFilled; isFilled = [myRect isFilled];
- メッセージ式は、別のメッセージ式内にネストすることができます。
[myRect setPrimaryColor:[otherRect primaryColor]];
- Objective-C では、クラスを定義することでオブジェクトを定義します。
- クラス名は大文字で始まり(「Rectangle」など)、インスタンス名は通常小文字で始まります(「myRect」など)。
- NSObject はルートクラスなので、スーパークラスはありません。
- Cocoa では、NSObject が他の全クラスの継承パスに当たります。
- 特別な動作を別のクラスから継承する必要のないクラスでも、NSObject クラスのサブクラスにするべきです。
- クラスは、実質的にデータ型を規定します。
- このデータ型は、クラスで定義されるデータ構造(インスタンス変数)だけでなく、定義に含まれている動作(メソッド)もベースにしています。
- sizeof 演算子の引数などのように、C 言語において型指定子を指定できる場所ならば、クラス名をソースコードに記述できます。
int i = sizeof(Rectangle);
- 静的な型定義
- id の代わりにクラス名を使用して、オブジェクトの型を指定することができます。
Rectangle *myRect;
- id がオブジェクトへのポインタとして定義されているのと同じように、オブジェクトはクラスへのポインタとして静的に型定義されています。
- オブジェクトは必ずポインタとして型定義されます。
- 型のイントロスペクション
- インスタンスは、実行時にその型を明らかにすることができます。
- isMemberOfClass: メソッドは NSObject クラスで定義されており、レシーバが特定のクラスのインスタンスかどうかをチェックします。
if ( [anObject isMemberOfClass:someClass] ) ...
- isKindOfClass: メソッドも NSObject クラスで定義されており、レシーバが特定のクラスを継承しているどうか、すなわちそのクラスのメンバかどうか(指定のクラスがレシーバに継承パスにあるかどうか)をチェックします。
if ( [anObject isKindOfClass:someClass] ) ...
- インスタンスの作成
id myRect; myRect = [Rectangle alloc];
- alloc メソッドは、新しいオブジェクトのインスタンス変数に動的にメモリを割り当て、すべてを 0 に初期化します。
- オブジェクトが有用であるためには、通常は完全に初期化する必要があります。その初期化を行うのが init メソッドの機能です。初期化は、通常、割り当ての直後に行います。
myRect = [[Rectangle alloc] init];
- 静的に型定義できるのはインスタンスだけです。
- クラスオブジェクトは、クラスのメンバではなく Class データ型に属するため、静的に型定義できません。
Rectangle *anObject;
- オブジェクト指向プログラミングの大部分は、新しいオブジェクトのコードを書くこと、つまり新しいクラスを定義することに費やされます。
- クラスのメソッドとインスタンス変数を宣言し、そのスーパークラスを指定するインターフェイス(.h)
- 実際にクラスを定義する実装(メソッドを実装するコードを含む)(.m)
- たとえば、Rectangle クラスは、Rectangle.h で宣言され、Rectangle.m で定義されます。
インタフェース
- クラスインタフェースの宣言は、コンパイラディレクティブ @interface で始まり、ディレクティブ @end で終わります(コンパイラに対する Objective-C のディレクティブはすべて「@」で始まります)。
@interface ClassName :ItsSuperclass { インスタンス変数宣言 } メソッド宣言 @end
- 宣言の 1 行目では、新しいクラス名を指定し、それをスーパークラスにリンクします。
- コロンとスーパークラス名を省略すると、新しいクラスはルートクラス(NSObject クラスのライバル)として宣言されます。
- インスタンス変数は、クラスの各インスタンスの一部をなすデータ構造です。
- Rectangle クラスで宣言できるインスタンス変数の一部を示します。
float width; float height; BOOL filled; NSColor *fillColor;
- クラスのメソッドを宣言します。
- クラスオブジェクトに使用されるメソッドの名前、つまりクラスメソッドの前にはプラス記号 を付けます。
+ alloc;
- クラスのインスタンスが使用できるメソッド、つまりインスタンスメソッド の前にはマイナス記号 を付けます。
- (void)display;
- メソッドの戻り型は、標準 C の型キャストの構文を使って宣言します。
- (float)radius;
- 引数型も同じ方法で宣言します。
- (void)setRadius:(float)aRadius;
- 戻り型や引数型を明示的に宣言しないと、メソッドやメッセージのデフォルト型、id と見なされます。
- 前述の alloc メソッドは id を返します。
- 複数の引数がある場合は、メソッド名の中でコロンの後に引数を宣言します。
- (void)setWidth:(float)width height:(float)height;
- 可変引数を持つメソッドは、関数と同様に、コンマと省略記号を使って引数を宣言します。
- makeGroup:group, ...;
インタフェースのインポート
#import "Rectangle.h"
- 同じファイルが 2 回以上はインクルードされないことが保証されています。
- すべての Objective-C 関連ドキュメントのコード例の中で、#include の代わりに使用されています。
他のクラスの参照
- インタフェースファイルはクラスを宣言し、スーパークラスをインポートすることで、NSObject からスーパークラスに至るまで、すべての派生クラスの宣言を自動的に含みます。
- インタフェースがその階層以外のクラスを記述している場合は、それらを明示的にインポートするか、@class ディレクティブで宣言する必要があります。
@class Rectangle, Circle;
- このディレクティブは、「Rectangle」と「Circle」がクラス名であることをコンパイラに知らせるだけです。インタフェースファイルをインポートするものではありません。
- インスタンス変数、戻り値、および引数を静的に型定義するときに、インタフェースファイルにクラス名を記述します。
- (void)setPrimaryColor:(NSColor *)aColor;
- インタフェースファイルの目的は、新しいクラスを他のソースモジュール(および他のプログラマ)に対して宣言することです。
実装
- クラスの定義は、宣言と非常によく似た構造になります。@implementation ディレクティブで始まり、@end ディレクティブで終わります。
@implementation ClassName :ItsSuperclass { インスタンス変数宣言 } メソッド宣言 @end
- すべての実装ファイルは、自身のインタフェースをインポートする必要があります。
- Rectangle.m は Rectangle.h をインポートします。
- 実装はインポートする宣言を繰り返す必要がないため、次のものは省略しても支障ありません。
- スーパークラスの名前
- インスタンス変数の宣言
#import "ClassName.h" @implementation ClassName メソッドの定義 @end
- クラスのメソッド は、C 関数のように 1 対の中括弧内に定義します。
+ alloc { ... } - (BOOL)isfilled { ... } - (void)setFilled:(BOOL)flag { ... }
可変引数を持つメソッドは、関数と同様に引数を処理します。
#import ... - getGroup:group, ... { va_list ap; va_start(ap, group); ... }
インスタンス変数の有効範囲
ディレクティブ | 意味 |
---|---|
@private | インスタンス変数を宣言するクラス内でのみ当該変数にアクセス可能。 |
@protected | インスタンス変数を宣言するクラス内および継承するクラス内で当該変数にアクセス可能。 |
@public | 対象インスタンス変数にどこからでもアクセス可能。 |
リンク
Apple
Core Data
ツール
その他
- Cocoa勉強会
- Cocoaの日々 - 2005年8月(Cocoaバインディングのサンプル)
- Cocoa倶楽部(Cocoaのメモリ管理)
- Cocoa探検隊
- Repeating Motif Wonderland - 繰返し紋様の世界 -(フリーウェアソースコード解説)
- Cocoaで遊ぼう!!
- Cocoaでいこう! Macらしく(MOSADeN に掲載された記事)
- Delegateの使い方(NSApplication、NSWindow、NSTextFieldを使ってDelegateの解説)
- Cocoa Break!(開発資料和訳)
- Cocoa Dev Central(各種チュートリアル)