【问题标题】:How to I pass @selector as a parameter?如何将@selector 作为参数传递?
【发布时间】:2010-10-30 06:54:53
【问题描述】:

对于方法:

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

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


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

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

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

【问题讨论】:

    标签: iphone objective-c selector


    【解决方案1】:

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

    【讨论】:

    • @cstack:如果你看这个问题,产生一个新线程是他 OP 试图做的事情。因此,我在示例中使用了相同的任务。但这种技术并不是专门用于生成新线程。
    【解决方案2】:

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

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

    【讨论】:

    • 这是最好的答案,希望我能让更多的人支持这个。
    • 这是更简单的方法 - 在我看来它应该是选择的答案
    【解决方案3】:

    使用 NSValue,像这样:

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

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

    【讨论】:

    • 我相信您在“选择器”之前缺少一个“&”符号,因此它最终成为“... value:&selector ...”而不是“... value:selector .. .".
    • 是的。感谢您的关注;我已经修好了。
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      如果您不想指定对象,请使用 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]; 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-12
        • 2016-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多