iOS-确保在主线程执行

74

我想知道如何在主线程上调用我的函数

如何确保我的函数主线程上被调用?

(这是我之前的一个问题的后续。)


我认为只有使用[NSObject performSelectorOnMainThread]调用您的委托方法的类才能被视为“安全”。否则,如果对象只是调用[NSObject performSelector],则您的委托方法将在调用者线程的上下文中运行。 - trojanfoe
4个回答

168
这将完成它:
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {

   //Your code goes in here
   NSLog(@"Main Thread Code");

}];

2
我觉得这种方式更容易,因为如果你这样做,每次想在主线程上执行某些操作时就不必创建新的方法。 - shoughton123
1
这个建议帮助我解决了一个奇怪的问题,当我将XCode升级到最新的iOS 6.1模拟器时,遇到了一个套接字编程的神秘挂起。代码在从套接字读取一些数据后立即写入套接字。由于某种奇怪的原因,在iOS 5.1模拟器中这样做非常好用,但在6.0或6.1中不行。使用这个建议在主线程上执行写操作解决了我的问题,并且它适用于所有模拟器版本和设备! - Luis Artola
1
所以我在上面的答案中使用了代码块:(dispatch_sync(dispatch_get_main_queue(), ^{ //Your code goes in here NSLog(@"Main Thread Code");
});)因为gcd被认为工作得很好,然而,我遇到了一个问题,即主线程不会优先处理,并且应用程序会在我拥有的iPod5之一中停止。我改用NSOperationQueue,它可以正常工作。奇怪的情况,但我想在这里记录一下。
- C0D3
这样做更好,因为我可以随意“抛出”任何代码,而不必为performselector设计一个函数。此外,从那里执行的任何内容也会在主线程上执行。谢谢! - lppier
虽然我更喜欢这个选项(看起来更好),但它的UI很慢(例如,进度更新滞后)。为此,您应该使用dispatch_async。 - Recycled Steel
显示剩余2条评论

139

当您使用的是 iOS >= 4 时

dispatch_async(dispatch_get_main_queue(), ^{
  //Your main thread code goes in here
  NSLog(@"Im on the main thread");       
});

4
提醒问题发起人,如果你已经在主线程上,这不是你想要做的事情。 - Firoze Lafeer
5
主线程卡住了!这是源代码:https://dev59.com/aGsz5IYBdhLWcg3wj4kc#7817170 - CarlJ
2
请参见https://dev59.com/n2035IYBdhLWcg3wC7YR(您应该能够使用dispatch_async,在主线程上不会出现问题)。 - Chris Prince
@ChrisPrince 谢谢提示,已编辑答案。 - CarlJ
使用dispatch_sync也能正常工作吗? - CyberMew
显示剩余2条评论

49

有没有任何规则可以遵循,以确保我的应用程序仅在主线程中执行自己的代码?

通常情况下,您不需要做任何事情来确保这一点——您列出的事项通常已经足够了。除非您正在与某些API交互,该API可能会生成一个线程并在后台运行您的代码,否则您将在主线程上运行。

如果您想确保,请尝试进行如下操作:

[self performSelectorOnMainThread:@selector(myMethod:) withObject:anObj waitUntilDone:YES];

在主线程上执行一个方法。(也有一个GCD等效的方式。)


你如何处理在后台运行代码的情况,即创建一个线程来执行代码? - 3rdeye7

12

我认为这很酷,尽管通常最好让方法的调用者负责确保在正确的线程上调用它。

if (![[NSThread currentThread] isMainThread]) {
    [self performSelector:_cmd onThread:[NSThread mainThread] withObject:someObject waitUntilDone:NO];
    return;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接