1

例如我有一个看起来像这样的方法

[self performSelectorOnMainThread:@selector(someMethod) 
                       withObject:data
                    waitUntilDone:YES];

其中“someMethod”来自另一个类。如果有可能,我该怎么做?另外,我想知道如何传递参数。

假设 someMethod 被定义为:

- (void)someMethod:(NSData *)data otherArg:(NSString *)arg;
4

5 回答 5

3

您需要替换self为定义该方法的类的实例。否则你会得到一个无法识别的选择器错误。另外,如果您要向其发送参数,请不要忘记在其:后面加上一个冒号 ( ) 。someMethod

于 2012-06-18T05:29:54.750 回答
3

是的,您也可以调用另一个类的选择器。

如果选择器是类方法 -

[ClassName performSelectorOnMainThread:@selector(someMethod:) 
                   withObject:data
                waitUntilDone:YES];

和方法签名是这样的 -

+ (void)someMethod:(returntype)somearg

如果选择器是实例方法 -

[classInstance performSelectorOnMainThread:@selector(someMethod:) 
                   withObject:data
                waitUntilDone:YES];

和方法签名是这样的 -

- (void)someMethod:(returntype)somearg
于 2012-06-18T05:31:01.717 回答
1

这取决于。如果 'self' 继承自实现的类someMethod,那么您当然可以这样做。但是您不能向其类(或祖先类)未实现该方法的对象发送消息。(嗯,你可以,但期待一个错误。)

您显示的代码段类似于:

[self someMethod:data];

除了someMethod:将在主线程上运行,而不是当前正在执行的任何线程。以这种方式看待它可能会帮助您记住接收者(self在这种情况下,但它可能是指向任何对象的指针)必须实现您正在发送的消息。

于 2012-06-18T05:35:48.487 回答
0

而不是 self,你用你想要执行选择器的类的实例替换它。

于 2012-06-18T05:30:02.093 回答
0

您要发送的消息带有两个参数,并且没有变体performSelectorOnMainThread:...将两个参数与消息一起传递。

最简单的方法是使用 Grand Central Dispatch 和块。如果您确定不会在主线程上执行此操作,则可以执行以下操作:

dispatch_sync(dispatch_get_main_queue(), ^{
    [otherObject someMethod:myData otherArg:@"my argument"];
});

但是,如果您在主线程上运行该代码,该代码将死锁——您的应用程序将挂起。

如果您可能想在已经在主线程上时执行此操作,则必须更加小心以避免死锁。我会这样做:

dispatch_block_t block = ^{
    [otherObject someMethod:myData otherArg:@"my argument"];
};

if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
    block();
} else {
    dispatch_sync(dispatch_get_main_queue(), block);
}
于 2012-06-18T06:02:31.457 回答