2013-07-24 32 views
8

Hiện tại, dispatch_get_current_queue không được dùng nữa trong iOS 6, làm cách nào để sử dụng dispatch_after để thực hiện điều gì đó trong hàng đợi hiện tại?Cách gửi_after trong hàng đợi hiện tại?

+0

Bạn có cần phải ở trên cùng một hàng đợi hoặc bạn có thể sử dụng một công văn đến một hàng khác (thông qua dispatch_get_global_queue hoặc get_main_queue) –

+0

Cần giữ nguyên. – Boon

+3

FYI, xem http: // stackoverflow.com/questions/13237417/thay thế-to-dispatch-get-current-queue-cho-hoàn-khối-in-ios-6, http://stackoverflow.com/questions/12842166/how-can-i-replace- deprecated-method-dispatch-get-current-queue-from-ios5-to-io và http://stackoverflow.com/questions/12806506/how-can-i-verify-that-i-am-running-on -a-given-gcd-queue-without-using-dispatch-g cho các cuộc thảo luận liên quan về chủ đề này. – Rob

Trả lời

5

Các liên kết khác nhau trong nhận xét không nói "tốt hơn là không nên làm điều đó". Họ nói rằng bạn không thể làm điều đó. Bạn phải vượt qua hàng đợi bạn muốn hoặc gửi đến hàng đợi đã biết. Hàng đợi công văn không có khái niệm "hiện tại". Các khối thường được nạp từ hàng đợi này đến hàng đợi khác (được gọi là "nhắm mục tiêu"). Khi bạn đang thực sự chạy, hàng đợi "hiện tại" không thực sự có ý nghĩa, và dựa vào nó có thể (và về mặt lịch sử đã làm) dẫn đến khóa chết. dispatch_get_current_queue() không bao giờ có nghĩa là để gửi đi; đó là một phương pháp gỡ lỗi. Đó là lý do tại sao nó đã được gỡ bỏ (vì mọi người đối xử với nó như thể nó có nghĩa là một cái gì đó có ý nghĩa).

Nếu bạn cần loại sách cao cấp, hãy sử dụng NSOperationQueue theo dõi hàng đợi ban đầu của nó (và có hàng đợi đơn giản hơn khiến hàng đợi ban đầu "có ý nghĩa hơn nhiều).

Có một số phương pháp được sử dụng trong UIKit thích hợp:

  • Vượt qua dispatch_queue gọi trở lại như một tham số (điều này có lẽ là phương pháp phổ biến nhất trong các API mới). Xem [NSURLConnection setDelegateQueue:] hoặc addObserverForName:object:queue:usingBlock: để biết các ví dụ. Lưu ý rằng NSURLConnection mong đợi một số NSOperationQueue, không phải là dispatch_queue. API cấp cao hơn và tất cả điều đó.
  • Gọi lại cho bất kỳ hàng đợi nào bạn đang truy cập và để người nhận xử lý nó. Đây là cách callback có truyền thống làm việc.
  • Yêu cầu có một runloop trên chuỗi cuộc gọi và lên lịch cuộc gọi lại của bạn trên runloop đang gọi. Đây là cách NSURLConnection lịch sử hoạt động trước hàng đợi.
  • Luôn thực hiện cuộc gọi lại của bạn trên một trong những hàng đợi nổi tiếng (đặc biệt là hàng đợi chính) trừ khi được thông báo khác. Tôi không biết bất cứ nơi nào mà điều này được thực hiện trong UIKit, nhưng tôi đã nhìn thấy nó thường trong mã ứng dụng, và là một cách tiếp cận rất dễ dàng hầu hết thời gian.
+2

Tôi có một số thông báo cuối cùng của bạn: nếu đây là một cuộc gọi lại (nói một trình xử lý hoàn thành, lỗi hoặc tiến trình) thì hàng đợi chính * sẽ là ứng cử viên ít nhất được chọn làm ngữ cảnh thực thi mặc định. Sử dụng hàng đợi chính làm tăng xác suất cho các khóa chết. Đây là một thói quen xấu từ các nhà thiết kế thư viện, xuất phát từ giả định ngu ngốc và giả, rằng khách hàng của tác vụ không đồng bộ muốn làm công cụ trên luồng chính "dù sao". Nhưng điều đó làm cho nó tồi tệ hơn. – CouchDeveloper

1

Tạo hàng đợi theo cách thủ công và gửi cả mã gọi điện và mã dispatch_after của bạn lên đó. Bằng cách đó bạn có thể đảm bảo rằng cả hai đoạn mã được chạy từ cùng một hàng đợi.

+0

Giả sử tôi không thể gửi mã gọi điện của tôi, nói rằng nó là từ một thư viện tĩnh. – Boon

+0

Trong trường hợp đó, sẽ có một số trợ giúp gián tiếp? Thay vì truyền mã bạn muốn gọi, hãy có một trình bao bọc của chính bạn gửi đến hàng đợi chính xác. –

0

Việc phải làm điều này có thể là do nhu cầu hack. Bạn có thể hack thông tin này bằng một lần hack khác:

id block = ^foo() { 
    [self doSomething]; 
    usleep(delay_in_us); 
    [self doSomehingOther]; 
} 

Thay vì usleep() bạn có thể xem xét lặp lại trong vòng lặp chạy.

Mặc dù vậy, tôi sẽ không đề xuất "cách tiếp cận" này. Cách tốt hơn là có một số phương thức lấy hàng đợi làm tham số và một khối làm tham số, trong đó khối được thực thi trên hàng đợi đã chỉ định.

Và, bằng cách này, có nhiều cách trong một khối thực hiện để kiểm tra xem nó chạy trên một đặc biệt hàng đợi - tương ứng trên bất kỳ mẹ hàng đợi của nó, miễn là bạn có một tham chiếu đến hàng đợi mà trước: sử dụng chức năng dispatch_queue_set_specificdispatch_get_specific.

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