有没有办法检查当前线程是否是Objective-C中的主线程?
我想做这样的事情。
- (void)someMethod
{
if (IS_THIS_MAIN_THREAD?) {
NSLog(@"ok. this is main thread.");
} else {
NSLog(@"don't call this method from other thread!");
}
}
答案 0 :(得分:155)
有像
这样的方法 - (BOOL)isMainThread
+ (BOOL)isMainThread
和+ (NSThread *)mainThread
答案 1 :(得分:21)
如果要在主线程上执行方法,可以:
- (void)someMethod
{
dispatch_block_t block = ^{
// Code for the method goes here
};
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_async(dispatch_get_main_queue(), block);
}
}
答案 2 :(得分:15)
在Swift3中
if Thread.isMainThread {
print("Main Thread")
}
答案 3 :(得分:12)
如果您想知道自己是否在主线程上,可以直接使用调试器。在您感兴趣的行设置一个断点,当您的程序到达时,请调用:
(lldb) thread info
这将显示有关您所关注的主题的信息:
(lldb) thread info
thread #1: tid = 0xe8ad0, 0x00000001083515a0 MyApp`MyApp.ViewController.sliderMoved (sender=0x00007fd221486340, self=0x00007fd22161c1a0)(ObjectiveC.UISlider) -> () + 112 at ViewController.swift:20, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
如果queue
的值为com.apple.main-thread
,那么您就是主线程。
答案 4 :(得分:6)
以下模式将确保在主线程上执行方法:
- (void)yourMethod {
// make sure this runs on the main thread
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:_cmd/*@selector(yourMethod)*/
withObject:nil
waitUntilDone:YES];
return;
}
// put your code for yourMethod here
}
答案 5 :(得分:3)
void ensureOnMainQueue(void (^block)(void)) {
if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) {
block();
} else {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
block();
}];
}
}
请注意我检查操作队列,而不是线程,因为这是一种更安全的方法
答案 6 :(得分:2)
两种方式。来自@ rano的回答,
[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
此外,
[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
答案 7 :(得分:2)
对于Monotouch / Xamarin iOS,您可以通过以下方式执行检查:
if (NSThread.Current.IsMainThread)
{
DoSomething();
}
else
{
BeginInvokeOnMainThread(() => DoSomething());
}
答案 8 :(得分:1)
Swift版
if (NSThread.isMainThread()) {
print("Main Thread")
}
答案 9 :(得分:0)
查看此答案让isOnMainQueue = (dispatch_queue_get_label(dispatch_get_main_queue())== dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL))
答案 10 :(得分:0)
import Foundation
extension DispatchQueue {
private struct QueueReference { weak var queue: DispatchQueue? }
private static let key: DispatchSpecificKey<QueueReference> = {
let key = DispatchSpecificKey<QueueReference>()
let queue = DispatchQueue.main
queue.setSpecific(key: key, value: QueueReference(queue: queue))
return key
}()
static var isRunningOnMainQueue: Bool { getSpecific(key: key)?.queue == .main }
}
if DispatchQueue.isRunningOnMainQueue { ... }
func test(queue: DispatchQueue) {
queue.async {
print("--------------------------------------------------------")
print("queue label: \(queue.label)")
print("is running on main queue: \(DispatchQueue.isRunningOnMainQueue)")
}
}
test(queue: DispatchQueue.main)
sleep(1)
test(queue: DispatchQueue.global(qos: .background))
sleep(1)
test(queue: DispatchQueue.global(qos: .unspecified))
--------------------------------------------------------
queue label: com.apple.root.background-qos
is running on main queue: false
--------------------------------------------------------
queue label: com.apple.root.default-qos
is running on main queue: false
--------------------------------------------------------
queue label: com.apple.main-thread
is running on main queue: true
答案 11 :(得分:0)
Here is a way to detect what the current queue is
extension DispatchQueue {
//Label of the current dispatch queue.
static var currentQueueLabel: String { String(cString: __dispatch_queue_get_label(nil)) }
/// Whether the current queue is a `NSBackgroundActivityScheduler` task.
static var isCurrentQueueNSBackgroundActivitySchedulerQueue: Bool { currentQueueLabel.hasPrefix("com.apple.xpc.activity.") }
/// Whether the current queue is a `Main` task.
static var isCurrentQueueMainQueue: Bool { currentQueueLabel.hasPrefix("com.apple.main-thread") }
}
答案 12 :(得分:-2)
UPDATE:似乎是不正确的解决方案,根据提到的queue.h标头@demosten
第一个想法是带给我的,当我需要时,这个功能就是这一行:
dispatch_get_main_queue() == dispatch_get_current_queue();
并且已经找到了接受的解决方案:
[NSThread isMainThread];
我的解决方案速度提高了2.5倍。
PS是的,我已经检查过,它适用于所有线程