SELオブジェクトしかない場合、いくつかの引数を持つセレクターを呼び出す簡単な方法があるはずです。正しい構文が見つからないようです。
-(MyClass*) init: (SEL)sel owner:(NSObject*) parent
{
int i =10;
[parent performSelector:sel:i ];
}
NSObject
のドキュメントをご覧ください。この場合:
_[parent performSelector:sel withObject:[NSNumber numberWithInt:i]];
_
(このメソッドは実際には NSObject
protocol のドキュメントに記載されています)。 _-[NSObject performSelector:withObject:]
_にはオブジェクト引数が必要なため、次のように親のクラスにラッパーを記述する必要があります
_-(void)myMethodForNumber:(NSNumber*)number {
[self myMethod:[number intValue]];
}
_
NSNumber
を開梱する。
非オブジェクト引数を直接受け取るメソッドを呼び出したい場合(たとえば、呼び出し先のソースを制御しておらず、カテゴリを追加したくない場合)は、 NSInvocation
:
_NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:parent];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv invoke];
_
余談ですが、メソッドはinit
メソッドのように見えますが、Objective-Cの正しい初期化子パターンに従っていません。スーパークラスの初期化子を呼び出す必要があり、その呼び出しからのnil
結果をテストする必要があり、初期化子メソッドからselfを返す必要があります。すべての場合において、Objective-C初期化メソッドは次のようになります。
_-(id)myInitMethod {
self = [super init];
if(self != nil) {
//perform initialization of self
}
return self;
}
_
その場合、メソッド(initメソッドの場合)は次のようになります。
_-(id) init: (SEL)sel owner:(NSObject*) parent
{
self = [super init];
if(self != nil) {
int i = 10;
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:parent];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv invoke];
}
return self;
}
_
よりObjective-Cになるように、イニシャライザの名前を-(id)initWithSelector:owner:
にも変更します。
バリー・ワークが言ったことは素晴らしいです。私は怠惰なプログラマーのための議論を変更しました
-(void)myMethodWith:(int)number andBOOL:(BOOL) someBool andStr:(NSString *)str{
NSLog(@"%d %d %@",number,someBool,str);
}
-(void) testMethod{
SEL sel = @selector(myMethodWith:andBOOL:andStr:);
int i = 10;
BOOL bol = YES;
NSString *str = @"hey baby !";
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:self];
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
[inv setArgument:&bol atIndex:3];
[inv setArgument:&str atIndex:4];
[inv invoke];
}
performSelector:withObject:
を使用したいトリッキーな部分はint
をNSObjectに変換することです。 performSelector
パラメータを使用するメッセージでint
を使用することはできません。代わりにid
を使用する必要があります。
NSObject Protocol Reference から:
aSelectorは、タイプidの単一の引数を取るメソッドを識別する必要があります。他の引数タイプと戻り値を持つメソッドの場合は、 NSInvocation を使用します。
その変更が行われると、次のことができます。
id arg = [NSNumber numberWithInt:10];
[parent performSelector:sel withObject:arg];
id
型の1つまたは2つのオブジェクトを引数として取るメソッドの場合、次を使用できます。
[parent performSelector:sel withObject:argument1];
または
[parent performSelector:sel withObject:argument1 withObject:argument2];
他の引数タイプのメソッドの場合、任意のメソッド呼び出しをカプセル化できるNSInvocation
を作成します。
以下を使用できます。
- (id)performSelector:(SEL)aSelector withObject:(id)anObject
- (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject
または、より複雑なメソッドを使用する必要がある場合は、NSInvocation
クラスを使用します