特に何も指定しなかったときのインスタンス変数の有効範囲は@protectedと同等。
以下ディレクティブ。
ディレクティブ | 意味 |
---|---|
@private | クラス内でのみアクセス可能 |
@protected | クラス内と、その継承されたクラスでのみアクセス可能 |
@public | どこからでもアクセス可能 |
@package | 意味不明 |
@packageは意味不明。private_externが何なのか知らない。
シンボルテーブルには登録しないってやつ?
androidの@hideみたいな感じ?
メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。
特に何も指定しなかったときのインスタンス変数の有効範囲は@protectedと同等。
以下ディレクティブ。
ディレクティブ | 意味 |
---|---|
@private | クラス内でのみアクセス可能 |
@protected | クラス内と、その継承されたクラスでのみアクセス可能 |
@public | どこからでもアクセス可能 |
@package | 意味不明 |
投稿者
atkonn
時刻:
23:10:00
0
コメント
ラベル: Objective-C, お勉強, メモ
レシーバが持つインスタンス変数への参照
インスタンス変数の名前そのままでアクセス可能。
- (void)setA:(BOOL)b { a = b; }レシーバが保持しているインスタンス変数aへアクセス
@interface ObjA { ObjB *objB; } @interface ObjB {
@public BOOL a; } @implementation ObjA - (void)methodA:(BOOL)b { objB->a = b; }
投稿者
atkonn
時刻:
22:43:00
0
コメント
ラベル: Objective-C, お勉強, メモ
@implementationで始まり、@endで終わる。
#import "この実装のインタフェース.h" @implementation クラス名 { インスタンス変数宣言 } メソッド定義インスタンス変数宣言は必要なければ省略可能。その歳は{}も省略する。
- (型)メソッド名 { // ここに実装を定義 }
#import "stdarg.h" - (void)methods: param1, ... { va_list ap; va_start(ap, param1); .... }
ラベル: Objective-C, お勉強, メモ
インタフェースが、その階層以外のクラス名を記述している場合は、
そのクラスのインタフェースファイルをインクルードするか、
@classディレクティブを記述する。
@class クラス名; @class クラス名, クラス名;@classディレクティブは、インタフェースをインクルードしない。
ラベル: Objective-C, お勉強, メモ
インタフェースの場合、そのインタフェースに依存する全てのソースにincludeする必要がある。
インタフェースファイルは通常以下のようにincludeする。
#import "インタフェースファイル.h"
ラベル: Objective-C, お勉強, メモ
クラスは以下の2つに分けて定義する。
1) インタフェース
2) 実装
通常インタフェースと実装は別々のファイルとし、インタフェースは.h、実装は.mという拡張子をもつ。
インタフェース
インタフェースはディレクティブ@interfaceで始まり、ディレクティブ @endで終わる。
クラスのインタフェースは以下のように定義する。
@interface クラス名 : スーパクラス { インスタンス宣言 } メソッド宣言 プロパティ宣言 @end
+ (戻り値の型)メソッド名; +(戻り値の型)メソッド名:(パラメータの型)パラメータ; +(戻り値の型)メソッド名:(パラメータの型)パラメータ 名前:(パラメータの型)パラメータ;
-(戻り値の型)メソッド名; -(戻り値の型)メソッド名:(パラメータの型)パラメータ; -(戻り値の型)メソッド名:(パラメータの型)パラメータ 名前:(パラメータの型)パラメータ;
- (void)methoddayo:param1, ...;
@property (attribute) Type propertyName;
投稿者
atkonn
時刻:
23:57:00
0
コメント
ラベル: Objective-C, お勉強, メモ
クラス名は以下の2つの場合にのみ使用できる。
投稿者
atkonn
時刻:
23:18:00
0
コメント
ラベル: Objective-C, お勉強, メモ
クラスオブジェクトはルートクラスのインスタンスメソッドを実行する権限があるらしい。
.
投稿者
atkonn
時刻:
23:09:00
0
コメント
ラベル: Objective-C, お勉強, メモ
クラスが静的変数やグローバル変数を使っている場合、initializeというメソッドで初期化するのが良いんでないかい、と書いてある。
ランタイムがinitializeメッセージを送るタイミングは以下のとおり。
1) メッセージを受信する前
2) 該当クラスのスーパークラスがinitializeメッセージを受信した後
よって、クラスは使用される前にinitializeメッセージを処理する機会が与えられる。
特に初期化する必要がなければ、initializeメソッドを実装する必要は無い。
注意点!
initializeを実装したスーパークラスObjAを継承したinitializeを実装しないクラスObjBがある場合、ObjBに対して送られたinitializeメッセージはObjBに該当するinitializeメソッドが
無いため、スーパークラスObjAのinitializeへと転送する。そのため、ObjAのinitializeメソッドが複数回実行されてしまう場合がある。
複数回実行されるのを防ぐために、以下のように実装する。
+(void)initialize { if (self == [ObjA class]) { // ここで初期化処理 } }
ラベル: Objective-C, お勉強, メモ
そんなものは無い。
グローバル変数やstatic変数で代用した例。
static ObjA *objA;
@implementation ObjA;
+(id)getInstance
{
どーのこーのどーのこーの
return objA;
}
もちろん
static ObjA *objA;
じゃなく、
ObjA *objA;
とすることも可能。
だけど、なるべく有効範囲を限定した方が有効、とのこと。
.
投稿者
atkonn
時刻:
21:28:00
0
コメント
ラベル: Objective-C, お勉強, メモ
allocメソッド
新しいオブジェクトのインスタンス変数を動的にメモリを割り当てる。
割り当てたインスタンス変数を0に初期化する。
クラスオブジェクトには少なくともallocのようなメソッドが1つ以上ある。
id str = [NSString alloc];
みたいな。
initメソッド
オブジェクトが有用であるためには、0で初期化するだけじゃなく
完全に初期化する必要があり、その初期化を行う。
通常allocの直後に行う。
クラスオブジェクトには少なくともinitのようなメソッドが1つ以上ある。
id str = [[NSString alloc] init];
とか。
ラベル: Objective-C, お勉強, メモ
ソースコード上では、クラスオブジェクトはクラス名として表される。
ex)
[NSString alloc];
メッセージ式で、単なるレシーバオブジェクトとして表される。
その他の場合、クラスまたはインスタンスに対してidクラスを返すよう要求することで
クラスオブジェクトを得られる。
ex)
id classObjDaYo = [NSString class];
NSString *strObj = [NSString @"aaa"];
id classObj2DaYo = [strObj class];
上記で、クラスオブジェクトはid型としているが、すべてのクラスオブジェクトは
Class型なので、Class型とすることもできる。
ex)
Class classObjDaYo = [NSString class];
.
ラベル: Objective-C, お勉強, メモ
実行時にインスタンスがどの型かを調べることができる。
調べるためには、NSObjectのメソッドが使える。
isMemberOfClass:
レシーバが、引数で指定されたクラスであるかどうか調べる。
[objA isMemberOfClass:ObjA];
objAはObjAクラスであるかどうか。
isKindOfClass:
レシーバが、引数で指定されたクラスを継承しているか、または属しているかを調べる。
.
ラベル: Objective-C, お勉強, メモ
クラス定義は追加的に定義する。
新しいクラスはすべて別のクラスをベースとする。
NSObjecgt
ルートクラスは普通はNSObject。
NSObjectはルートクラスなのでスーパクラスが無い。
ルートクラスを定義することも可能だけど、止めといた方がいいってさ。
オブジェクトとして動作させるコードが書いてあるらしい。
インスタンス変数
普通に継承
メソッド
普通
メソッドのオーバライド
普通.
インスタンス変数のオーバライド
できない。
抽象クラス
継承されることが目的であったり、主に継承されることが目的のクラス。
通常、単独では不完全。
ただし、Objective-Cにはクラスを抽象クラスとしてマークするような構文は無い。
抽象クラスであってもallocできる。
ラベル: Objective-C, お勉強, メモ
Objective-Cではクラスを定義することでオブジェクトを定義する。
クラスの定義は一種のオブジェクトのプロトタイプ。
コンパイラによってクラスに1つだけアクセス可能な「クラスオブジェクト」(ファクトリオブジェクト)が作成される。
このクラスオブジェクトにより構築されるオブジェクトが、クラスのインスタンス。
慣習的にクラス名は大文字で始まる。
インスタンス名は小文字で始まる。
.
投稿者
atkonn
時刻:
23:27:00
0
コメント
ラベル: Objective-C, お勉強, メモ
アクセサメソッドを呼び出す[]の代わりにドットを使うことができる。
直接インスタンス変数を変更しているわけではなく、アクセサメソッド呼び出しの「構文糖」。
[ObjA setValue:10];
と書く代わりに
ObjA.value = 10;
と書くことができる。
同様に
int a = [ObjA getValue];
と書く代わりに
int a = ObjA.value;
と書くことができる。
直接ObjAのインスタンス変数valueにアクセスしているわけではなく、
ObjAのアクセサメソッドを経由している。
自分の保有するインスタンス変数にアクセスする場合、self.(selfドット)をつけて
アクセスすれば、アクセサメソッド経由になる。もちろんself.を付けなければ
直接インスタンス変数にアクセスする。
[self setValue:10];
は
self.value = 10;
と同等だけど、
value = 10;
とは違う。インスタンス変数に直接アクセスしている。
へへ。
.
投稿者
atkonn
時刻:
23:07:00
0
コメント
ラベル: Objective-C, お勉強, メモ
受信側のオブジェクトと、メッセージは、メッセージが送信されるまで結合されない。
なので、実際にどのメソッドが実行されるかは、実行時にだけ知ることができる。
さらに、送信するメッセージ(メソッドセレクタ)も実行時に決定させることが可能。
(メッセージ(メソッドセレクタ)を変数にする)
.
ラベル: Objective-C, お勉強, メモ
異なるオブジェクトでも同じセレクタ名を持つのであれば
同じメッセージに対して、応答することができる。
@implementation ObjBase;
- (void)methodBase:(id)obj
{
[obj methodYahoo];
}
@implementation ObjA;
- (void)methodYahoo
{
NSLog(@"ObjA DA YO!");
}
@implementation ObjB;
- (void)methodYahoo
{
NSLog(@"ObjB DA YO!");
}
であれば、
[[[ObjBase alloc] init] methodBase:[[ObjA alloc] init]];
がいけるとすれば、
[[[ObjBase alloc] init] methodBase:[[ObjB alloc] init]];
もいけるって感じかどうなのか。
.
ラベル: Objective-C, お勉強, メモ
あるオブジェクトに対して何か実行させたいなら、そのオブジェクトに対してメッセージを送るんだそうだ。
その書式は以下。
[receiver message];
これを「メッセージ式」というらしい。
receiver は、メッセージを受信するオブジェクト。
messageは、receiverが実行すべきこと。
ランタイムシステムはメッセージが送信されると、receiverの持つ全てのメソッドの中から適切なメソッドを選んで呼び出す。
なので、message部分はreceiverのメソッド実装を「選択」することから
セレクタと呼ぶこともあるとのこと。
message部の書き方
AオブジェクトのBメソッドを実行する場合
[A B];
Aオブジェクトの引数1つのBメソッドを実行する場合
メソッド名の直後にコロンを置いて、その直後に引数の値を指定する。
[A B:10];
Aオブジェクトの複数の引数を持つBメソッドを実行する場合
2つ目以降の引数には引数名とコロン、そして引数の値を指定する。
[A B:10 C:20 D:30];
セレクタ名(Javaで言えばシグネチャ?)は、メソッド名とパラメータ名で成る。
上記の例だと
B:C:D:
となるとのこと。コロンが3つあるのは引数を3つ取るため。
戻り値や引数の型はセレクタ名には含まれない。
Aオブジェクトの可変引数を持つBメソッドを実行する場合
コロンの後にカンマで区切って指定する。
[A B:10,20,30];
セレクタ名にはカンマは含まれない。
なので[A B:10,20,30]のセレクタ名は
B:
となる。
値を返すメッセージ式
メッセージ式で指定されたメソッドが値を返す場合、メッセージ式は値を返すことができる。
A = [B C];
BオブジェクトのCメソッドを実行した結果、その戻り値をAに代入。
メッセージ式の中にメッセージ式
メッセージ式はネストできるので以下のように書くことができる。
[A B:[C D]];
上記は、CオブジェクトのDメソッドの戻り値をAオブジェクトのBメソッドのパラメータとしている。
nilへのメッセージ
nilへメッセージ送信可能。
nilへのメッセージパターン
1) メソッドがオブジェクトを返す場合、nilを返す。
ObjB *objB = nil;
ObjA *objA = [ObjB methodReturnsObjA];
の場合objAはnil。
2) メソッドが以下の型を返す場合、メソッドは0を返す。
ポインタ型、sizeof(void*)以下のサイズの整数スカラ、float、double、long double、long long
@implementation ObjA;
- (float)methodReturnsFloat;
の場合、
ObjA *objA = nil;
[objA methodReturnsFloat];
は、0.0を返す。
3) メソッドがstructを返す場合は、そのstructのすべてのフィールドに0.0を返す。
4) 上記、1)〜3)以外の場合は、返す値は不定。
そんだけ。
.
ラベル: Objective-C, お勉強, メモ
オブジェクトは実行時に動的に型定義されるらしい。
どうやって型を特定するかというと、
振る舞い(メソッド)とデータ(インスタンス変数)の種類
で特定するっぽい。
で、これはisa変数ってのがやるみたい。
.
投稿者
atkonn
時刻:
19:56:00
0
コメント
ラベル: Objective-C, お勉強, メモ