2010-08-23 34 views
96

Có cách nào để kiểm tra xem luồng hiện tại có phải là luồng chính trong Objective-C không?Kiểm tra xem chủ đề hiện tại có phải là chủ đề chính

Tôi muốn làm điều gì đó như thế này.

- (void)someMethod 
    { 
    if (IS_THIS_MAIN_THREAD?) { 
     NSLog(@"ok. this is main thread."); 
    } else { 
     NSLog(@"don't call this method from other thread!"); 
    } 
    } 
+0

điều gì sai về việc gọi phương thức từ các chủ đề khác? –

Trả lời

143

Hãy xem NSThread API documentation.

Có nhiều phương pháp như

- (BOOL)isMainThread

+ (BOOL)isMainThread

+ (NSThread *)mainThread

+2

Cảm ơn! Đó là điều tôi muốn. –

-2

UPDATE: dường như đó không phải là giải pháp đúng, theo tiêu đề queue.h như đã đề cập @demosten

Ý nghĩ đầu tiên đã được đưa đến với tôi, khi tôi đang cần chức năng này là dòng:

dispatch_get_main_queue() == dispatch_get_current_queue(); 

Và đã nhìn vào dung dịch được chấp nhận:

[NSThread isMainThread]; 

giải pháp của tôi nhanh hơn 2,5 lần.

PS Và vâng, tôi đã kiểm tra, nó hoạt động cho tất cả các chủ đề

+3

Làm cho tinh thần - phương pháp của bạn bỏ qua chi phí của hệ thống nhắn tin thời gian chạy obj-c. Mặc dù nếu bạn đang sử dụng kỹ thuật này, tôi muốn nói rằng nó có một mùi mã xấu, có lẽ là do tối ưu hóa sớm. – ArtOfWarfare

+4

dispatch_get_current_queue() không được chấp nhận từ iOs 6.0 –

+30

Bạn có thể đọc điều này trong phần mô tả hàng đợi queue.h của Apple nơi dispatch_get_current_queue() được xác định: 'Khi dispatch_get_current_queue() được gọi trên chủ đề chính, nó có thể hoặc không thể trả lại cùng giá trị như dispatch_get_main_queue(). So sánh , hai cách này không phải là cách hợp lệ để kiểm tra xem mã có đang thực thi trên chuỗi chính .' – demosten

6

Các mô hình sau đây sẽ đảm bảo một phương pháp được thực thi trên các chủ đề chính:

- (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 
} 
+0

'_cmd' sẽ tự động sử dụng phương pháp mà đoạn mã của bạn được dán vào ʕ • ᴥ • ʔ –

12

Nếu bạn muốn có một phương pháp để có được thực hiện trên chủ đề chính, bạn có thể:

- (void)someMethod 
{ 
    dispatch_block_t block = ^{ 
     // Code for the method goes here 
    }; 

    if ([NSThread isMainThread]) 
    { 
     block(); 
    } 
    else 
    { 
     dispatch_async(dispatch_get_main_queue(), block); 
    } 
} 
+4

từ một lời giải thích về cách câu trả lời mới khác với câu trả lời hiện có. –

+1

Đây là quá mức cần thiết, nếu một số công việc * phải * được thực hiện trên luồng chính, không sử dụng trong việc kiểm tra xem bạn có đang ở trên luồng chính hay không. Chỉ cần làm 'NSOperationQueue.mainQueue(). AddOperationWithBlock {// công việc của bạn ở đây}' – Eric

+0

@Eric Tôi đồng ý, nhưng nếu bạn muốn thực hiện ngay lập tức phương thức nếu đã có trong chủ đề chính? Trong đề xuất của bạn, phương thức luôn được gửi đi để được thực hiện sau đó thông qua hàng đợi hoạt động chính. – boherna

11

Nếu bạn muốn biết bạn có đang trên luồng chính hay không, bạn có thể chỉ cần sử dụng trình gỡ lỗi. Thiết lập một breakpoint tại dòng bạn quan tâm, và khi chương trình của bạn đạt đến nó, gọi đây là:

(lldb) thread info

này sẽ hiển thị thông tin về các chủ đề bạn đang ở trên:

(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

Nếu giá trị cho queuecom.apple.main-thread, thì bạn đang ở trên chuỗi chính.

2

Hai cách.Từ câu trả lời @ rano của,

[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD"); 

Ngoài ra,

[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD"); 
2

Đối MonoTouch/Xamarin iOS bạn có thể thực hiện việc kiểm tra theo cách này:

if (NSThread.Current.IsMainThread) 
{ 
    DoSomething(); 
} 
else 
{ 
    BeginInvokeOnMainThread(() => DoSomething()); 
} 
1

Swift Version


if (NSThread.isMainThread()) { 
    print("Main Thread") 
} 
11

Trong Swift3

if Thread.isMainThread { 
    print("Main Thread") 
} 
2
void ensureOnMainQueue(void (^block)(void)) { 

    if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) { 

     block(); 

    } else { 

     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

      block(); 

     }]; 

    } 

} 

lưu ý rằng tôi kiểm tra hàng đợi hoạt động, không phải là chuỗi, vì đây là cách tiếp cận an toàn hơn

+0

Đây phải là câu trả lời được chấp nhận, chủ đề chính! = Hàng đợi chính – railwayparade

Các vấn đề liên quan