2012-08-23 22 views
74

Bất cứ ai có thể giải thích cho số NSRunLoop là gì? vì vậy, tôi biết NSRunLoop là nội dung nào đó được kết nối với NSThread phải không? Vì vậy, giả sử tôi tạo một Chủ đề nhưHiểu NSRunLoop

NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil]; 
[th start]; 

-(void) someMethod 
{ 
    NSLog(@"operation"); 
} 

vì vậy sau khi Chủ đề này kết thúc quyền làm việc của mình? tại sao sử dụng RunLoops hoặc nơi để sử dụng? từ tài liệu của Apple Tôi đã đọc một cái gì đó nhưng nó không rõ ràng cho tôi, vì vậy hãy giải thích đơn giản vì nó có thể

+0

Câu hỏi này quá rộng trong phạm vi. Vui lòng tinh chỉnh câu hỏi của bạn thành một cái gì đó cụ thể hơn. –

+1

lúc đầu tôi muốn biết những gì làm trong NSRunLoop genereal và làm thế nào nó kết nối với chủ đề – taffarel

Trả lời

158

Vòng lặp chạy là một trừu tượng (trong số những thứ khác) cung cấp cơ chế xử lý nguồn đầu vào hệ thống (ổ cắm, cổng , tệp, bàn phím, chuột, bộ hẹn giờ, v.v.).

Mỗi NSThread có vòng lặp chạy riêng của nó, có thể được truy cập thông qua phương thức currentRunLoop.

Nói chung, bạn không cần phải truy cập trực tiếp vòng lặp chạy, mặc dù có một số thành phần (mạng) có thể cho phép bạn chỉ định vòng lặp chạy mà chúng sẽ sử dụng cho xử lý I/O. Một vòng lặp chạy cho một chuỗi nhất định sẽ đợi cho đến khi một hoặc nhiều nguồn đầu vào của nó có một số dữ liệu hoặc sự kiện, sau đó kích hoạt trình xử lý đầu vào thích hợp để xử lý từng nguồn đầu vào đã sẵn sàng "."

Sau khi làm như vậy, nó sẽ quay trở lại vòng lặp của nó, xử lý dữ liệu nhập từ nhiều nguồn khác nhau và "ngủ" nếu không có việc phải làm.

Đó là mô tả mức khá cao (cố gắng tránh quá nhiều chi tiết).

EDIT

Một cố gắng để giải quyết các nhận xét. Tôi đã chia thành từng mảnh.

  • nó có nghĩa là tôi có thể truy cập chỉ/chạy để chạy vòng lặp bên trong thread phải không?

Thật vậy. NSRunLoop không phải là chủ đề an toàn và chỉ nên truy cập từ ngữ cảnh của chuỗi đang chạy vòng lặp.

  • có ví dụ đơn giản nào về cách thêm sự kiện để chạy vòng lặp không?

Nếu bạn muốn giám sát cổng, bạn chỉ cần thêm cổng đó vào vòng lặp chạy và sau đó vòng chạy sẽ xem cổng đó cho hoạt động.

- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode 

Bạn cũng có thể thêm một bộ đếm thời gian một cách rõ ràng với

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode 
  • những gì có nghĩa là sau đó nó sẽ trở lại vòng lặp của nó?

Vòng lặp sẽ xử lý tất cả các sự kiện sẵn sàng cho mỗi lần lặp (theo chế độ của nó).Bạn sẽ cần phải nhìn vào tài liệu để khám phá về các chế độ chạy, vì đó là một chút vượt ra ngoài phạm vi của một câu trả lời chung.

  • là vòng lặp chạy không hoạt động khi tôi bắt đầu chủ đề?

Trong hầu hết các ứng dụng, vòng lặp chạy chính sẽ tự động chạy. Tuy nhiên, bạn có trách nhiệm bắt đầu vòng lặp chạy và trả lời các sự kiện đến cho các chủ đề bạn quay.

  • có thể thêm một số sự kiện vào chuỗi chạy bên ngoài chuỗi không?

Tôi không chắc chắn ý bạn là gì ở đây. Bạn không thêm sự kiện vào vòng lặp chạy. Bạn thêm nguồn đầu vào và nguồn hẹn giờ (từ chuỗi sở hữu vòng lặp chạy). Các vòng lặp chạy sau đó xem chúng cho hoạt động. Bạn có thể, tất nhiên, cung cấp dữ liệu đầu vào từ các chủ đề và quy trình khác, nhưng đầu vào sẽ được xử lý bởi vòng lặp chạy đang theo dõi các nguồn trên luồng đang chạy vòng lặp chạy.

  • không có nghĩa là đôi khi tôi có thể sử dụng chạy vòng lặp để chặn chủ đề trong một thời gian

Thật vậy. Trong thực tế, một vòng lặp chạy sẽ "ở lại" trong một xử lý sự kiện cho đến khi xử lý sự kiện đó đã trở lại. Bạn có thể thấy điều này trong bất kỳ ứng dụng nào đơn giản là đủ. Cài đặt trình xử lý cho bất kỳ hành động IO nào (ví dụ: nhấn nút) sẽ ngủ. Bạn sẽ chặn vòng lặp chạy chính (và toàn bộ giao diện người dùng) cho đến khi phương thức đó hoàn thành.

Điều tương tự cũng áp dụng cho bất kỳ vòng lặp chạy nào.

tôi đề nghị bạn đọc tài liệu sau đây về chạy vòng:

https://developer.apple.com/documentation/foundation/nsrunloop

và cách chúng được sử dụng trong bài:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1

+1

nó có nghĩa là tôi chỉ có thể truy cập/chạy để chạy vòng lặp bên trong thread phải không? là có bất kỳ ví dụ đơn giản làm thế nào để thêm sự kiện để chạy vòng lặp? những gì có nghĩa là nó sau đó sẽ trở lại vòng lặp của nó? chạy vòng lặp không hoạt động khi tôi bắt đầu thread? có thể thêm một số sự kiện vào vòng lặp chạy Thread bên ngoài luồng không? có nghĩa là đôi khi tôi có thể sử dụng vòng lặp chạy để chặn luồng trong một thời gian? – taffarel

+1

+1 Tuyệt vời, súc tích và rất hữu ích – Madbreaks

+0

"Cài đặt trình xử lý cho bất kỳ hành động IO nào (ví dụ: nhấn nút) sẽ ngủ". Bạn có nghĩa là nếu tôi tiếp tục giữ ngón tay của tôi trên nút, nó sẽ tiếp tục chặn các thread trong một thời gian ?! – Honey

6

Runloops là chút giống như một hộp nơi những thứ vừa xảy ra.

Về cơ bản trong Runloop, bạn sẽ xử lý một số sự kiện và sau đó quay lại. HOẶC trả lại nếu nó không xử lý bất kỳ sự kiện nào trước khi hết thời gian chờ. Bạn có thể nói nó tương tự như NSURLConnections không đồng bộ, Xử lý dữ liệu trong nền mà không can thiệp vào vòng lặp hiện tại của bạn và đồng thời bạn yêu cầu đồng bộ dữ liệu. Có thể thực hiện điều này bằng trợ giúp của Runloop, nơi giữ lại NSURLConnection không đồng bộ của bạn và cung cấp dữ liệu vào thời gian gọi. Bạn có thể sử dụng runloop như sau: -

NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; 
while (YourBoolFlag && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) 
loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; 

trong runloop này nó sẽ chạy cho đến khi bạn hoàn thành một số công việc khác của bạn và thiết lập YourBoolFlag để sai.

Tương tự, bạn có thể sử dụng chúng trong chuỗi.

Hy vọng điều này sẽ giúp bạn.

1

Chạy vòng là gì táchtương tác ứng dụng từ dòng lệnh công cụ.

  • Công cụ dòng lệnh được khởi chạy với thông số, thực hiện lệnh, sau đó thoát.
  • Ứng dụng tương tác chờ cho người dùng nhập, phản hồi, sau đó tiếp tục chờ.

Từ here

Chúng cho phép bạn đợi cho đến khi vòi sử dụng và đáp ứng cho phù hợp, chờ đợi cho đến khi bạn có được một completionHandler và áp dụng kết quả của nó, chờ đợi cho đến khi bạn có được một bộ đếm thời gian và thực hiện một chức năng. Nếu bạn không có một runloop thì bạn không thể nghe/chờ đợi cho người dùng vòi, bạn không thể chờ đợi cho đến khi một cuộc gọi mạng đang xảy ra, bạn không thể được đánh thức trong x phút.

Cũng từ this comment:

đề Bối cảnh không có runloops riêng của họ, nhưng bạn chỉ có thể thêm một. Ví dụ. AFNetworking 2.x đã làm. Nó đã được thử nghiệm và thực sự kỹ thuật cho NSURLConnection hoặc NSTimer trên nền chủ đề, nhưng chúng tôi không làm điều này chính chúng ta nữa, vì các API mới hơn loại bỏ sự cần thiết phải làm như vậy. Nhưng dường như URLSession không, ví dụ như, here is simple request, chạy [xem bảng điều khiển bên trái của hình ảnh] xử lý hoàn trên hàng đợi chính, và bạn có thể thấy nó có một chạy vòng trên sợi nền