SomeClass
というクラスメソッドを持つObjective CインターフェイスsomeMethod
があるとします。
@interface SomeClass : NSObject {
}
+ (id)someMethod;
@end
他のインターフェイスでは、次のようなクラスで動的にsomeMethod
を呼び出すヘルパーメソッドが必要です。
[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];
invokeSelector
の実装は何ですか?まったく可能ですか?
- (void)invokeSelector:(SEL)aSelector forClass:(Class)aClass {
// ???
}
の代わりに:
[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];
コール:
[[SomeClass class] performSelector:@selector(someMethod)];
例(GNUstepを使用して...)
ファイルA.h
#import <Foundation/Foundation.h>
@interface A : NSObject {}
- (NSString *)description;
+ (NSString *)action;
@end
ファイルA.m
#import <Foundation/Foundation.h>
#import "A.h"
@implementation A
- (NSString *)description
{
return [NSString stringWithString: @"A"];
}
+ (NSString *)action
{
return [NSString stringWithString:@"A::action"];
}
@end
どこか別の場所:
A *a = [[A class] performSelector:@selector(action)];
NSLog(@"%@",a);
出力:
2009-11-22 23:32:41.974 abc[3200] A::action
http://www.cocoabuilder.com/archive/cocoa/197631-how-do-classes-respond-to-performselector.html からの素晴らしい説明:
「Objective-Cでは、クラスオブジェクトはその階層のルートクラスのすべてのインスタンスメソッドを取得します。これは、NSObjectから派生するすべてのクラスオブジェクトが、performSelector:を含むすべてのNSObjectのインスタンスメソッドを取得することを意味します。」
Objective-Cでは、クラスもオブジェクトです。ただし、ルートオブジェクトのクラスメソッド(CocoaではNSObject
またはNSProxy
)を呼び出すことができるため、クラスオブジェクトの扱いは異なります。
したがって、NSObject
で定義されているすべてのインスタンスメソッドをクラスオブジェクトで使用することも可能であり、クラスメソッドを動的に呼び出す正しい方法は次のとおりです。
[aClass performSelector:@selector(aSelector)];
Apple docs はもう少し具体的です。
これを自分で実装するべきではありません。
NSObjectプロトコルには performSelector:
これを正確に行うメソッド。
この組み込みメソッドはあなたが望むものですか?
id objc_msgSend(id theReceiver, SEL theSelector, ...)
(この関数については ランタイムリファレンスドキュメント を参照してください。)