简体   繁体   English

如何将@selector作为参数传递?

[英]How to I pass @selector as a parameter?

For the method: 对于方法:

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

How do I pass in a @selector? 如何传入@selector? I tried casting it to (id) to make it compile, but it crashes in runtime. 我尝试将它转换为(id)以使其编译,但它在运行时崩溃。


More specifically, I have a method like this: 更具体地说,我有一个像这样的方法:

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

It crashes. 它崩溃了。 How do I pass in the selector without crashing, so that the new thread can call the selector when the thread is ready? 如何在不崩溃的情况下传入选择器,以便新线程可以在线程准备好时调用选择器?

The problem here isn't passing a selector to a method, per se, but passing a selector where an object is expected. 这里的问题不是将选择器传递给方法本身,而是将选择器传递给期望对象。 To pass a non-object value as an object, you can use NSValue . 要将非对象值作为对象传递,可以使用NSValue In this case, you'll need to create a method that accepts an NSValue and retrieves the appropriate selector. 在这种情况下,您需要创建一个接受NSValue并检索适当选择器的方法。 Here's an example implementation: 这是一个示例实现:

@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

You can convert between selectors and string objects using the NSStringFromSelector() and NSSelectorFromString() functions. 您可以使用NSStringFromSelector()NSSelectorFromString()函数在选择器和字符串对象之间进行转换。 So you can just pass string objects instead. 所以你可以只传递字符串对象。

Alternately, if you don't want to change your methods, you can create an NSInvocation to create an invocation for your method call (since it can set up invocations with non-object arguments), and then to call it do [NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil]; 或者,如果您不想更改方法,可以创建一个NSInvocation来为您的方法调用创建一个调用(因为它可以设置带有非对象参数的调用),然后调用它做[NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];

Use NSValue, like so: 使用NSValue,如下所示:

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

NSValue is intended as an object-wrapper for arbitrary non-object types. NSValue旨在作为任意非对象类型的对象包装器。

If you don't want to specify an object just use nil. 如果您不想指定对象,请使用nil。

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

If you need to pass an object to the selector it would look something like this. 如果你需要将一个对象传递给选择器,它将看起来像这样。

Here I'm passing a string to the method "setText". 这里我将一个字符串传递给方法“setText”。

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


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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM