2009-05-31 6 views
51

@selectorをパラメータとして渡す方法は?方法については

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:(id)SELECTOR]; 

は、どのように私は@selectorに渡すのですか?私はそれをコンパイルするために(id)にキャストしようとしましたが、実行時にクラッシュします。それがクラッシュした

+(void)method1:(SEL)selector{ 
[NSThread detachNewThreadSelector:@selector(method2:) toTarget:self withObject:selector]; 
} 


具体的には、私はこのような方法があります。スレッドが準備完了したときに新しいスレッドがセレクタを呼び出せるように、セレクタをクラッシュさせずに渡すにはどうすればよいですか?

答えて

67

ここでの問題は、セレクタをメソッド自体に渡すのではなく、オブジェクトが期待されるセレクタを渡すことです。非オブジェクト値をオブジェクトとして渡すには、NSValueを使用できます。この場合、NSValueを受け取り、適切なセレクタを取得するメソッドを作成する必要があります。

@implementation Thing 
- (void)method:(SEL)selector { 
    // Do something 
} 

- (void)methodWithSelectorValue:(NSValue *)value { 
    SEL selector; 

    // Guard against buffer overflow 
    if (strcmp([value objCType], @encode(SEL)) == 0) { 
     [value getValue:&selector]; 
     [self method:selector]; 
    } 
} 

- (void)otherMethodShownInYourExample { 
    SEL selector = @selector(something); 
    NSValue *selectorAsValue = [NSValue valueWithBytes:&selector objCType:@encode(SEL)]; 
    [NSThread detachNewThreadSelector:@selector(methodWithSelectorValue:) toTarget:self withObject:selectorAsValue]; 
} 
@end 
+0

+50優秀!私はこれを行う方法を決して覚えていません... – bentford

+0

なぜあなたは新しいスレッドでそのビットをしなければなりませんか? – cstack

+2

@cstack:あなたが質問を見ると、新しいスレッドを作成することは、彼がOPのやっていることです。だから私は私の例で同じ仕事をしました。しかし、このテクニックは、新しいスレッドを産み出すことに特有のものではありません。 – Chuck

0

あなただけnilを使用してオブジェクトを指定しない場合。

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:nil]; 

オブジェクトをセレクタに渡す必要がある場合は、次のようになります。

ここでは、文字列をメソッド "setText"に渡します。

NSString *string = @"hello world!"; 
[NSThread detachNewThreadSelector:@selector(setText:) toTarget:self withObject:string]; 


-(void)setText:(NSString *)string { 
    [UITextField setText:string]; 
} 
+0

更新された質問をご覧ください。ありがとうございました! – erotsppa

4

使用NSValueそうのように、::ここでの実装例を示します

+(void)method1:(SEL)selector { 
    NSValue *selectorValue = [NSValue value:&selector withObjCType:@encode(SEL)]; 
    [NSThread detachNewThreadSelector:@selector(method2:) 
          toTarget:self 
          withObject:selectorValue]; 
} 

NSValueは、任意の非オブジェクト型のオブジェクト・ラッパーとして意図されています。

+0

"セレクタ"の前に "&"記号がなく、 "... value:セレクタ..."ではなく "... value:&selector ..."になると思います。 – Senseful

+0

真。気づいてくれてありがとう。私はそれを修正しました。 –

41

NSStringFromSelector()NSSelectorFromString()の機能を使用して、セレクタと文字列オブジェクトを変換できます。だから、代わりに文字列オブジェクトを渡すことができます。

また、メソッドを変更したくない場合は、NSInvocationを作成して(非オブジェクト引数で呼び出しを設定できるため)メソッド呼び出しの呼び出しを作成してからdo [NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];

+0

これはより多くのupvotesを必要とします –

+0

これはたくさんの最高の答えです、私はこれをupvoteするより多くの人々を得ることができたらいいですね。 –

+0

多くのおかげで、これは私が必要としたものでした。 – amergin

関連する問題