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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/932801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:38:29  来源:igfitidea点击:

How to I pass @selector as a parameter?

iphoneobjective-cselector

提问by erotsppa

For the method:

对于方法:

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

How do I pass in a @selector? I tried casting it to (id) to make it compile, but it crashes in runtime.

我如何传入@selector?我尝试将它转换为 (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?

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

回答by Chuck

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. In this case, you'll need to create a method that accepts an NSValue and retrieves the appropriate selector. Here's an example implementation:

这里的问题不是将选择器传递给方法本身,而是在需要对象的地方传递选择器。要将非对象值作为对象传递,您可以使用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

回答by user102008

You can convert between selectors and string objects using the NSStringFromSelector()and NSSelectorFromString()functions. So you can just pass string objects instead.

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

Alternately, if you don't want to change your methods, you can create an NSInvocationto 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];

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

回答by BJ Homer

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 旨在作为任意非对象类型的对象包装器。

回答by ennuikiller

回答by Brandon Schlenker

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]; 
}