2013-07-11 24 views
9

Tôi đang lập trình một ứng dụng sử dụng các yêu cầu web không đồng bộ bằng NSURLConnection, vì vậy tôi có nhiều luồng đang chạy. Để đảm bảo rằng logic chính của ứng dụng của tôi xảy ra trên một chủ đề, tôi đang sử dụng số lượng lớn performSelectorOnMainThread:waitUntilDone:. Đôi khi, mặc dù, tôi đang chạy này trên chủ đề chính, mà piqued sự tò mò của tôi.Nếu performSelectorOnMainThread: waitUntilDone: được gọi từ luồng chính, khi nào nó sẽ thực thi?

Nếu performSelectorOnMainThread:waitUntilDone: được gọi trong khi trong chuỗi chính? Nó có hoạt động giống như chỉ performSelector: không? Điều gì xảy ra nếu waitUntilDone:YES? Nếu nó là NO thì sao?

EDIT: Tôi thấy rằng khi waitUntilDone:YES, bộ chọn được thực hiện (gần như) ngay lập tức, nhưng tôi không thể tìm ra khi nào được thực hiện nếu waitUntilDone:NO.

+0

Tôi đã thấy rằng khi 'waitUntilDone:' là 'YES', bộ chọn được thực hiện (gần như) ngay lập tức, nhưng tôi không thể tìm ra khi nó được thực thi nếu' waitUntilDone: 'là' NO'. – Jumhyn

+0

Trình gỡ lỗi không trợ giúp ở đây? Chỉ cần tìm khi một luồng mới được sinh ra. –

+0

@Cole, 'performSelector' ** OnMainThread: ** sẽ không tạo chuỗi, đặc biệt khi nó được gọi là _from_ chuỗi chính. –

Trả lời

13
performSelectorOnMainThread:withObject:waitUntilDone: 

là phương thức gửi tin nhắn theo số main thread trong số application của bạn. Ở đây boolean giá trị trong tham số waitUntilDone: chỉ định rằng bạn có muốn chặn main thread của mình để thực thi được chỉ định selector hay không.

ví dụ -

nếu bạn viết hai lines-

[self performSelectorOnMainThread:@selector(print) withObject:nil waitUntilDone:YES]; 

NSLog(@"Hello iPhone"); 

và đây là phương pháp in -

- (void) print 
{ 
    NSLog(@"Hello World"); 
} 

sau đó bạn sẽ nhận được o này/p

Hello World 
Hello iPhone 

vì vậy nó linh sam t tạm dừng việc thực hiện của bạn in main thread và "Hello World" và sau đó thực hiện chủ đề chính một lần nữa và in "Hello iPhone" bởi vì bạn chỉ định YES trong waitUntilDone:

nhưng nếu bạn chỉ định NO trong waitUntilDone: sau đó nó sẽ in như thế này -

Hello iPhone 
Hello World 

nó cho thấy rõ ràng rằng nó đưa yêu cầu của bạn thực hiện các quy định selector trong một queue và là hệ điều hành được nó main thread miễn phí nó thực hiện quý vị yêu cầu.

Calling performSelectorOnMainThread:withObject:waitUntilDone: hoặc từ main thread hoặc một secondary thread không thực hiện bất kỳ sự khác biệt trong đó là thực hiện, nó phụ thuộc vào những gì bạn định tại waitUntilDone:

để biết thêm -

NSObject Class Reference

+0

@saabdip +1 để có giải thích tốt đẹp. – iLearner

+1

Tôi chắc chắn nitpicking, nhưng bạn đang sai trong "Nếu bạn chỉ định' NO', sau đó nó sẽ in 'Hello iPhone \ nHelloWorld' ". Trong thực tế, và cho trang web cuộc gọi không thực hiện trên luồng chính, thứ tự của hai đầu ra là * không * xác định được. Nếu không, nếu trang gọi thực hiện trên luồng chính, luồng chính sẽ không bị chặn - thay vào đó nếu _waitUntilDone_ là 'YES' thì bộ chọn sẽ được thực hiện ngay lập tức. ;) Phát biểu cuối cùng của bạn quá mơ hồ. – CouchDeveloper

1
If the current thread is also the main thread, and you pass YES, 
the message is performed immediately, otherwise the perform is 
queued to run the next time through the run loop. 

Nếu CÓ, nó có thể được thực hiện trước khi trả về performSelectorOnMainThread:withObject:waitUntilDone:.

Tôi thấy rằng khi đợiUntilDone: là CÓ, bộ chọn được thực hiện (gần như) ngay lập tức, nhưng tôi không thể tìm ra khi nó được thực thi nếu waitUntilDone: là NO.

Bit về vòng lặp chạy: Chuỗi chính của bạn có vòng lặp chạy. Điều này nhiều hơn hoặc ít hơn ngăn chặn một chuỗi thoát khỏi. Một vòng lặp chạy quản lý một danh sách việc cần làm. Khi công việc của nó hoàn tất, nó sẽ tạm ngưng thực hiện chuỗi đó trong một thời gian. Sau đó, nó thức dậy sau đó và thấy nếu có việc phải làm.

Số lượng công việc có thể thay đổi rất nhiều (ví dụ: có thể thực hiện một số bản vẽ hoặc tệp thực sự nặng giữa thời gian nó hoạt động và điểm chọn của bạn được thực hiện. nhưng nó phải là đủ để biết cách thức hoạt động và cách thức triển khai thêm công việc để vòng lặp chạy

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

1

Nếu waitUntilDone:.. được YES nó hoạt động như một cuộc gọi chức năng ngay lập tức

Nếu waitUntilDone : là NO rồi nó xếp hàng cuộc gọi cùng với tất cả các cuộc gọi của các chủ đề khác.

Phương pháp này hàng đợi thông điệp trên vòng chạy của các chủ đề chính sử dụng vòng lặp chạy chung chế độ-có nghĩa là, các chế độ liên quan đến việc NSRunLoopCommonModes liên tục. Là một phần của vòng lặp chạy bình thường của nó xử lý, chủ đề chính dequeues tin nhắn (giả sử nó là chạy trong một trong các chế độ vòng lặp chạy phổ biến) và gọi phương thức mong muốn.

Như đã lưu ý ở trên, những thứ như vẽ và I/O được ưu tiên hơn bất kỳ thứ gì trong hàng đợi. Một khi chủ đề chính được xung quanh để có thời gian cho dịch vụ xếp hàng trong vòng lặp sự kiện tiếp theo, có một vài chi tiết khác làm cho nó không hoàn toàn đơn giản như đếm đầu tiên trước tiên:

1) dispatch_async() chặn bỏ qua các chế độ .

2) Biến thể performSelector với đối số chế độ cụ thể - theo dõi sự kiện, có thể được ưu tiên hơn so với đối số chế độ chung mặc định trong vòng lặp chạy trong chế độ cụ thể đó.

Theo nguyên tắc chung, nếu bạn muốn các hành vi thời gian có thể dự đoán, bạn nên sử dụng các hàm gửi GCD cấp thấp không tính đến các cân nhắc cấp cao hơn như chế độ vòng lặp chạy.

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