方法:
[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:(id)SELECTOR];
如何传入@selector?我尝试将它转换为(id)以使其编译,但它在运行时崩溃。
更具体地说,我有一个这样的方法:
+(void)method1:(SEL)selector{
[NSThread detachNewThreadSelector:@selector(method2:) toTarget:self withObject:selector];
}
它崩溃了。如何在没有崩溃的情况下传入选择器,以便新线程可以在线程就绪时调用选择器?
答案 0 :(得分: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
答案 1 :(得分:42)
您可以使用NSStringFromSelector()
和NSSelectorFromString()
函数在选择器和字符串对象之间进行转换。所以你可以改为传递字符串对象。
或者,如果您不想更改方法,可以创建NSInvocation
来为方法调用创建调用(因为它可以使用非对象参数设置调用),然后到称之为[NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];
答案 2 :(得分:4)
使用NSValue,如下所示:
+(void)method1:(SEL)selector {
NSValue *selectorValue = [NSValue value:&selector withObjCType:@encode(SEL)];
[NSThread detachNewThreadSelector:@selector(method2:)
toTarget:self
withObject:selectorValue];
}
NSValue旨在作为任意非对象类型的对象包装器。
答案 3 :(得分:2)
答案 4 :(得分: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];
}