2012-12-16 32 views
8

thể trùng lặp:
What is the difference between dispatch_get_global_queue and dispatch_queue_create?Sự khác nhau giữa hàng đợi toàn cầu và hàng đợi của người dùng là gì?

tôi thấy một số phương pháp sử dụng UCLN, nhưng một số trong số họ có thể làm điều đó như thế này:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
dispatch_async(queue, ^{ 

    dispatch_sync(dispatch_get_main_queue(), ^{ 

    }); 
}); 

nhưng những người khác có thể làm điều đó như này:

imageQueue_ = dispatch_queue_create("com.company.app.imageQueue", NULL); 
dispatch_async(imageQueue_, ^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 

     }); 
    }); 

Sự khác nhau là gì? Nếu tôi muốn tải xuống nhiều hình ảnh từ web, điều này tốt hơn?

Trả lời

19

Cách tốt nhất để khái niệm hàng đợi là trước tiên nhận ra rằng ở cấp độ rất thấp, chỉ có hai loại hàng đợi: nối tiếp và đồng thời.

Hàng đợi nối tiếp là đơn nhất, nhưng không được cam kết. Nếu bạn cung cấp cho một loạt các nhiệm vụ cho mỗi hàng đợi nối tiếp, nó sẽ chạy chúng mỗi lần, chỉ sử dụng một luồng tại một thời điểm. Khía cạnh không cam kết là hàng đợi nối tiếp có thể chuyển sang một luồng khác giữa các nhiệm vụ. Hàng đợi nối tiếp luôn chờ một công việc hoàn thành trước khi chuyển sang mục tiếp theo. Do đó các nhiệm vụ được hoàn thành theo thứ tự FIFO. Bạn có thể tạo bao nhiêu hàng đợi nối tiếp khi cần.

Hàng đợi chính là hàng đợi nối tiếp đặc biệt. Không giống như các hàng đợi nối tiếp khác, mà không được cam kết, trong đó họ "đang hẹn hò" nhiều chủ đề nhưng chỉ một lần, hàng đợi chính là "kết hôn" với chủ đề chính và tất cả các tác vụ được thực hiện trên đó. Hàng đợi chính hoạt động tốt với runloop của chuỗi chính để các hoạt động nhỏ không chặn giao diện người dùng và các bit quan trọng khác. Giống như tất cả các hàng đợi nối tiếp, các tác vụ được hoàn thành theo thứ tự FIFO.

Nếu hàng đợi nối tiếp là một vợ chồng, thì hàng đợi đồng thời là không liên quan. Họ sẽ gửi nhiệm vụ cho bất kỳ chủ đề có sẵn hoặc thậm chí tạo chủ đề mới tùy thuộc vào tải hệ thống. Họ có thể thực hiện nhiều tác vụ đồng thời trên các chủ đề khác nhau. Điều quan trọng là các tác vụ được gửi đến hàng đợi toàn cầu là an toàn luồng và giảm thiểu các tác dụng phụ. Các tác vụ được gửi để thực hiện theo thứ tự FIFO, nhưng thứ tự hoàn thành không được đảm bảo.

Đưa nó trở lại, tất cả các hàng đợi toàn cầu là đồng thời và tất cả hàng đợi của người dùng là nối tiếp.

Nếu mục tiêu của bạn là tải xuống hình ảnh, bạn có thể muốn có hàng đợi (người dùng) nối tiếp. Tải xuống hình ảnh có nhiều điều về băng thông. Bạn thường chỉ muốn làm một (hoặc một vài) tại một thời điểm.

chỉnh sửa: bài đăng trên blog mở rộng trên câu trả lời ở trên: http://amattn.com/2013/08/28/grand_central_dispatch_gcd_summary_syntax_best_practices.html

+0

Cảm ơn bạn đã trả lời! – Jackie

+0

Từ kinh nghiệm của tôi, câu trả lời này không chính xác. Hàng đợi của người dùng có thể được tạo (và chức năng) như một hàng đợi đồng thời. – Guy

3

Nếu bạn sử dụng dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); GCD sẽ tự động tạo đủ luồng để bạn xử lý công việc và sử dụng nhiều lõi nếu có thể.

Mặt khác, nếu bạn sử dụng imageQueue_ = dispatch_queue_create("com.company.app.imageQueue", NULL); bạn nhận được hàng đợi nối tiếp và hành vi Đầu tiên trong lần xuất phát đầu tiên.

Nếu bạn không lo lắng về an toàn luồng hoặc thứ tự mà công việc của bạn quay trở lại, thì hãy sử dụng phương pháp đầu tiên.

+0

cảm ơn câu trả lời tuyệt vời. Vì vậy, nói rằng bạn chỉ đơn giản là kết nối với một máy chủ để có được một số json, bằng cách sử dụng dataWithContentsOfURL :. Bạn sẽ sử dụng cái nào - cái đầu tiên? Không có mối quan tâm về lệnh trả lại; và tôi đoán không có mối lo ngại về an toàn luồng. Vì vậy - chỉ cần sử dụng hàng đợi toàn cầu? {có lẽ chỉ với ưu tiên mặc định} Chúc mừng! – Fattie

+1

"nếu bạn không lo lắng về sự an toàn của luồng" - người ta phải luôn lo lắng về an toàn luồng! – Maq

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