Geometry 関数
NSBundle
NSDictionary
NSFileManager
NSMutableAttributedString
NSNumber
NSScanner
NSString
NSTimer
Graphic 関数
NSApplication
NSBezierPath
NSCell
NSColor
NSCursor
NSCustomImageRep
NSDocument
NSDocumentController
NSDragging
NSEvent
NSFontManager
NSGraphicsContext
NSImage
NSMenu
NSOutlineView
NSPanel
NSPopUpButton
NSResponder
NSScrollView
NSString 追加
NSTableColumn
NSTableView
NSTextStorage
NSTextView
NSToolbar
NSView
NSWindow
NSWorkspace
その他
.nib ウィンドウ
Views パレット
クラス
インスタンス変数
メソッド
-メソッドを評価する
-メソッドの返り値を調べる
CFXML
Carbon Event
Carbon Graphics
Cocoa で日本語
メソッド
-メソッドを評価する
-メソッドの返り値を調べる
その他

- Miscellaneous-
メソッド

Miscellaneous - メソッド
メソッドを評価する
Keywords: instanceRespondToSelector, respondsToSelector

Objective-C は late binding な言語。これって、メソッドに返事ができるかどうかは、評価するまで分からない、ってことを意味する。それならば、評価をしてみよう!てなわけで、プログラム中でのメソッドの評価の仕方の話だ。

セレクタを評価するためのメソッドとして、NSObject に instancesRespondToSelector: が、NSObject protocol として respondsToSelector: が定義されている。

Foundation/NSObject.h
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;
- (BOOL)respondsToSelector:(SEL)aSelector;

さて、この 2 つはどうやって使い分けるのか?まず、instanceRespondToSelector: から。こいつは、そのクラスのインスタンスがセレクタを受け付けるかどうかを判別する。ということは、インスタンスメソッドは判別できるけど、クラスメソッドには反応しないんだ。次の例を参照。

(sample)
    // It returns YES
    [NSString instancesRespondToSelector:@selector(length)];

    // It returns NO
    [NSString instancesRespondToSelector:@selector(string)];

上の例では、NSString を調べている。length は NSString のインスタンスメソッドだから、YES を返す。それに対して、string はクラスメソッドになるから、 NO を返すんだ。

続いて respondsToSelector:。こいつは、このメッセージの受け手がそのセレクタに反応できるかどうかを評価するんだ。たとえば、NSString のインスタンスに対して投げてやると次のような感じ。

(sample)
    NSString* str = [NSString string];

    // It returns YES
    [str respondsToSelector:@selector(length)];

    // It returns NO
    [str respondsToSelector:@selector(string)];

インスタンスである str は、length には反応するが string には反応できない。では、これを NSString に対して投げてやる。

(sample)
    // It returns NO
    [NSString respondsToSelector:@selector(length)];

    // It returns YES
    [NSString respondsToSelector:@selector(string)];

という風に、length には NO だが、string には YES を返す。クラスである NSString はクラスメソッドに反応できるからだ。

というわけで、どちらを使うかはお好み次第で。


Miscellaneous - メソッド
メソッドの返り値を調べる
Keywords: methodReturnType, methodReturnLength

次は、メソッドの返り値を調べてみよう。これには NSMethodSignature の methodReturnTypemethodReturnLength を使う。

Foundation/NSMethodSignature.h
- (const char *)methodReturnType;
- (unsigned)methodReturnLength;

methodRetrunType は、メソッドの返り値の型を Objective-C encoding で返すんだ。だから、結果を比較するには @encode を使わないといけないところを注意。

(sample)
    NSString* string = [NSString string];
    NSMethodSignature* signature;

    // For 'length'
    signature = [string methodSignatureForSelector:@selector(length)];
    if (strcmp([signature methodReturnType], @encode(unsigned int)) == 0) {
        ...
    }

    // For 'copy'
    signature = [string methodSignatureForSelector:@selector(copy)];
    if (strcmp([signature methodReturnType], @encode(id)) == 0) {
        ...
    }

    // For 'pathComponents'
    signature = [string methodSignatureForSelector:@selector(pathComponents)];
    if (strcmp([signature methodReturnType], @encode(id)) == 0) {
        ...
    }

こんな感じで使える。methodReturnType の結果を strcmp() で比較しないといけないところに注意。また、ヘッダでは NSArray* を返している pathComponents は、id 型として認識しないといけない。返り値型が NSArray* を取る、という情報は、コンパイルをした時点で id 型に丸められてしまうようだ。



[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer Center] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論] [panther-dev]

mailto: mkino@xd5.so-net.ne.jp