51

对于方法:

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

我如何传入@selector?我尝试将其转换为 (id) 以使其编译,但它在运行时崩溃。


更具体地说,我有这样的方法:

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

它崩溃了。如何在不崩溃的情况下传入选择器,以便新线程在线程准备好时可以调用选择器?

4

5 回答 5

68

这里的问题不是将选择器传递给方法本身,而是将选择器传递到预期对象的位置。要将非对象值作为对象传递,您可以使用NSValue. In this case, you'll need to create a method that accepts an NSValue and retrieves the appropriate selector. 这是一个示例实现:

@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
于 2009-05-31T21:13:55.413 回答
43

NSStringFromSelector()您可以使用andNSSelectorFromString()函数在选择器和字符串对象之间进行转换。所以你可以只传递字符串对象。

或者,如果您不想更改您的方法,您可以创建一个NSInvocation来为您的方法调用创建一个调用(因为它可以使用非对象参数设置调用),然后调用它 do[NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];

于 2011-04-23T01:58:07.297 回答
4

使用 NSValue,如下所示:

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

NSValue 旨在作为任意非对象类型的对象包装器。

于 2009-05-31T21:14:48.097 回答
2

请参阅:将方法作为参数传递

于 2009-05-31T20:54:21.553 回答
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]; 
}
于 2009-05-31T20:55:22.613 回答