Objective-C のメソッドは、Java または C++ のメソッドと同じではありません。それらはメッセージであり、クラスやオブジェクトから独立して存在します。Photo.hに( CocoaDevCentral から取得) を書き込む場合:
#import <Cocoa/Cocoa.h>
@interface Photo : NSObject {
NSString* caption;
NSString* photographer;
}
- caption;
- photographer;
@end
クラスにはキャプションと写真家オブジェクトがあり、メッセージとPhoto
に応答すると言っています。これは、これらの 2 つの項目のコードを記述する以前のプロパティの方法でした。caption
photographer
が応答できるPhoto.m
ように、2 つのメッセージの実装を提供するコードを記述します。Photo
しかし、オブジェクトへの送信caption
を妨げるものは何もありません。それは、私たちが犬に何を言い、何を聞くかについての古いファー サイドの漫画のようなものです。実行時にエラーが発生します。
では、応答方法がわからないオブジェクトにメッセージを送信するとどうなるでしょうか? 特に何もしていないのであれば、
- ランタイム システムは、メッセージをタイプ のものにパッケージ化します
SEL
。
doesNotRecognizeSelector:
そのセレクターを持つオブジェクトにメッセージを送信します。
NSObject
オブジェクトは、 を発生させる実装から継承しますNSInvalidArgumentException
。
ただし、その前に、メソッドをオーバーライドして介入する機会がいくつかあります。
+ (BOOL) resolveInstanceMethod:(SEL)aSEL
これにより、実行時に実装をインストールできます。
- (id)forwardingTargetForSelector:(SEL)aSelector
これにより、別のオブジェクトを指定してメッセージを受け入れることができます。
- (void)forwardInvocation:(NSInvocation *)anInvocation
これにより、メッセージを任意の方法で処理できます。
Objective-C がブロックを獲得する前は、関数型プログラミングに転送を使用するライブラリが多数ありました。すべてがメッセージを理解するNSArray
ofがあるとします。次に、すべての口座の残高を別の に集めたいとします。ループする代わりに、ライブラリはメッセージ付きのカテゴリを提供し、次のように記述します。Account
balance
NSArray
NSArray
collect
NSArray *accounts = ...;
NSArray *balances = [[accounts collect] balance];
の結果にはメッセージ[accounts collect]
の実装がありません。balance
どうしてですか? collect
図書館から提供されています。代わりに、のすべてのメンバーにメッセージを送信し、それらから新しい を作成するforwardInvocation:
実装があります。最近ではブロックを使用することもありますが、それは非常に簡潔で強力な手法でした。balance
accounts
NSArray
enumerateObjectsUsingBlock: