2011-08-17 55 views
16

Tôi cần một cách tiết kiệm để nói: "iOS, tôi muốn phương pháp này được thực thi a.s.a.p., nhưng KHÔNG trong vòng lặp chạy vòng lặp này. Vào thời điểm sớm nhất trong lần tiếp theo, nhưng vui lòng không ở trong phần này. Cảm ơn bạn."Cách gọi phương thức a.s.a.p. nhưng sớm nhất trong vòng lặp chạy tiếp theo?

Ngay bây giờ tôi luôn luôn làm việc đó như thế này:

[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0]; 
[self doSomeOtherThings]; 

Với giả định rằng -doSomeOtherThings sẽ luôn luôn được thực hiện TRƯỚC -doSomethingInNextRunLoop.

Các tài liệu nói:

Xác định một sự chậm trễ từ 0 không nhất thiết gây ra selector là thực hiện ngay lập tức. Công cụ chọn vẫn được xếp hàng đợi trên vòng lặp hoạt động của luồng và được thực hiện càng sớm càng tốt.

Vì vậy, về cơ bản nó có thể xảy ra rằng phương pháp này được gọi ngay lập tức như thể tôi vừa gửi một thông điệp trực tiếp, gây -doSomethingInNextRunLoop được thực hiện trước khi -doSomeOtherThings?

Làm cách nào để đảm bảo chắc chắn nó sẽ được gọi là a.s.a.p. nhưng KHÔNG BAO GIỜ bao giờ trong cùng vòng lặp chạy lặp lại này?

Để làm rõ từ ngữ: Với vòng lặp chạy, tôi có nghĩa là chuỗi chính và lặp lại trong đó tất cả các phương thức đều phải trả lại cho đến khi luồng lại sẵn sàng cho các sự kiện mới.

Trả lời

9

Nếu bạn lo lắng rằng Apple có thể một ngày nào đó trường hợp đặc biệt bị trễ 0, bạn luôn có thể chỉ định độ trễ 1e-37 hoặc lâu hơn. Mặc dù tài liệu cho performSelector:withObject:afterDelay: có thể dễ dàng được đọc để đảm bảo rằng bộ chọn sẽ luôn được lên lịch cho vòng lặp chạy lặp tiếp theo. Nếu bạn lo lắng rằng một ngày nào đó Apple có thể bị chậm trễ hơn một số ràng buộc tùy ý, bạn luôn có thể thử sử dụng performSelector:target:argument:order:modes: của NSRunLoop mà tài liệu cụ thể nói sẽ lên lịch thực hiện cho vòng lặp tiếp theo của vòng lặp chạy.

+0

Thật tuyệt vời! Một loại để giảm bớt điều này sẽ có ý nghĩa. – openfrog

0

Chắc chắn bạn chỉ làm điều này;

[self doSomeOtherThings]; 
[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0]; 

Đảm bảo thứ tự thực hiện mà bạn muốn.

+1

Nó không phải lúc nào cũng thuận tiện (hoặc có thể) để sắp xếp lại mã theo cách đó trong những trường hợp phức tạp hơn ví dụ nhỏ này được sử dụng để minh hoạ. – Anomie

+0

Không thực sự. Có những lý do tốt để thực hiện mọi thứ trong vòng lặp chạy lặp NEXT. Một trong số đó: Cho phép inbetween làm mới UI. Cải thiện hiệu suất nhận thức. Trong số nhiều người khác. Bên cạnh đó, Anomie là đúng. – openfrog

+0

Để chắc chắn, phản ứng từ Anomie chạm vào móng trên đầu, tôi chỉ chỉ ra rằng trong một số trường hợp, sắp xếp lại mã có thể giải quyết được vấn đề. Một chút giống như nhà văn khối, đôi khi devs được treo lên trên giải quyết một vấn đề một cách cụ thể khi trên thực tế có một kế hoạch bên B. FWIW Tôi không nhận thức được bất kỳ trường hợp mà các tiêu chuẩn performSelector: withObject: afterDelay: 0 kết quả trong chặn và sử dụng kỹ thuật này thường xuyên để tối ưu hóa mã UI do người khác viết. – Roger

1

Tôi nghĩ rằng bạn kết luận từ việc đọc tài liệu là sai.

Vì vậy, về cơ bản nó có thể xảy ra rằng phương pháp này được gọi ngay lập tức như thể tôi vừa gửi một thông điệp trực tiếp

số Các phần của tài liệu bạn trích dẫn nói rằng bộ chọn luôn xếp hàng đợi trên chạy vòng lặp, không có vấn đề gì. Vì vậy, nó sẽ không bao giờ được thực hiện giống như một thông điệp trực tiếp.

Câu đầu tiên với "không nhất thiết" có thể là một chút gây hiểu nhầm, nhưng tôi nghĩ câu thứ hai nên thực sự làm rõ rằng những gì bạn sợ không phải là cồng kềnh xảy ra.

+0

Hy vọng rằng bạn đúng, bởi vì tôi đặt cược rất nhiều người phụ thuộc vào nó ong xếp hàng đợi cho lần lặp tiếp theo. Tuy nhiên, có một số sự không chắc chắn. – openfrog

6

Khá tầm thường sử dụng GCD (Grand Central Dispatch):

dispatch_async (dispatch_get_main_queue(), ^{ 
    NSLog (@"This stuff runs in the next iteration of the main run loop"); 
}); 
Các vấn đề liên quan