sandbox

Scala, Android, Architecture, Management, Service Design あたりを主戦場としております

Objective-C 2.0 プログラミング言語を読む

最近、iPhone をはじめとして Cocoa アプリを書ける様になりたいので Objective-C を勉強してます。

まずは言語の基礎からということで、ADC で公開されている「Objective-C 2.0 プログラミング言語」を
見ているのですが、サンプルコードを読んだりしている時、ここどうなってたっけ、と見返すことが結構あります。
その場合、ちょっと説明の記述が冗長で邪魔なので、自分が思いだせるレベルでまとめたものをメモ。

動的型定義

型を限定したくない、つまり型を動的に扱いたい場合は、
オブジェクトへのポインタである id 型を使用する。

id anObject;

静的な型定義

クラスへのポインタとして宣言する。

Rectangle *myRect;

特定のクラスのインスタンスかどうかを調べる

if ([myRect isMemberOfClass:Shape])

特定のクラスを継承しているかどうかを調べる

if ([myRect isKindOfClass:Shape])

メッセージ構文

[receiver message]

ネストもできる。

nil へのメッセージ送信

メソッドがオジェクト、ポインタ型、スカラー値、float、double、long double、long long を返す場合 > 0 を返す

メソッドが struct を返す場合 > 0.0 を返す

それ以外 > 不定

レシーバのインスタンス変数

メソッドは、レシーバのインスタンス変数にアクセス出来る。

動的バインディング

メッセージの場合は実行時に実際に実行されるメソッドが決定される。
メソッド名は、メソッド実装を選択する役割を持つ為、メソッド名のことを「セレクタ」ともいう。

クラス

クラス毎に1つだけクラスオブジェクトが生成される。
クラスオブジェクトは、新しいインスタンスの構築方法を知っているオブジェクトである。
その為、伝統的にこのオブジェクトのことを「ファクトリオブジェクト」という。

継承

単一継承、オーバーライドなど Java とほぼ同じ。

親クラスへのアクセスは super
自分自身へのアクセスは self

ルートクラスは NSObject

クラスオブジェクト

型名のみでアクセス。
動的に型定義したり、他のクラスからメソッドを継承すること等が出来る。

id versionNumber = [Rectangle version];
class rectClass = [Rectangle class];
  • クラスとスーパークラスの名前
  • インスタンス変数のセットを記述したテンプレート
  • メソッド名およびその戻り値と引数の型の宣言
  • メソッドの実装

インスタンスの作成

id myRect = [[Rectangle alloc] init];

alloc - オブジェクトの生成、メモリの確保
init - オブジェクトの初期化
initWith* etc - 引数付きのオブジェクトの初期化

変数とクラスオブジェクト

クラスのすべてのインスタンスでデータを共有する場合

int GlobalVariable;

@implementation MyClass
...

static を使用した Singleton の例

static MyClass *SharedInstance;

@implementation MyClass {

+ (MyClass *) sharedInstance
{
    return SharedInstance;
}

クラスオブジェクトの初期化

initialize メソッドを実装する。
継承時、親の initialize メソッドを連鎖的に呼ばれる為、
下記の様に、初期化ロジックが1回だけ実行されるようにしなければならない。

+ (void) initialize
{
    static BOOL initialized = NO;
    if (!initialized) {
        // initialize
        initialized = YES;
    }
}

ルートクラスのメソッド

クラスオブジェクトはルートインスタンスメソッドを実行出来る。

ソースコードにおけるクラス名

型名として使用する。

Rectangle *anObject;

レシーバとして使用する。

isKindOfClass:[Rectangle class]

文字列からクラスオブジェクトを取得する

NSClassFromString(@"Rectangle")