2013-02-06 28 views
7

Về cơ bản, tôi có một bộ dữ liệu trong một NSDictionary, nhưng để thuận tiện, tôi đang thiết lập một số NSArray s với dữ liệu được sắp xếp và lọc theo một vài cách khác nhau. Dữ liệu sẽ đến qua các luồng khác nhau (khối) và tôi muốn đảm bảo chỉ có một khối tại một thời điểm sửa đổi kho dữ liệu của tôi.@ không đồng bộ khối so với GCD dispatch_async()

Tôi đã gặp rắc rối khi thiết lập hàng đợi công văn vào chiều nay, và sau đó tình cờ gặp một bài đăng về số @synchronized làm cho nó có vẻ giống như những gì tôi muốn làm.

Vì vậy, những gì tôi đã ngay bây giờ là ...

// a property on my object 
@property (assign) dispatch_queue_t matchSortingQueue; 

// in my object init 
_sortingQueue = dispatch_queue_create("com.asdf.matchSortingQueue", NULL); 

// then later... 
- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    dispatch_async(_sortingQueue, ^{ 
     // do stuff... 
    }); 
} 

Và câu hỏi của tôi là, tôi có thể chỉ thay thế tất cả những điều này với những điều sau?

- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    @synchronized (self) { 
     // do stuff... 
    }; 
} 

... Và sự khác biệt giữa hai trường hợp là gì? Tôi nên cân nhắc điều gì?

+0

'@ synchronization' thực sự chậm. Tôi không thể tìm thấy số liệu tôi đang tìm kiếm ngay bây giờ, nhưng cũng có thể xem https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html. – Richard

+0

Nếu dữ liệu của bạn đến qua cùng một hàng đợi công văn (cùng một chuỗi) thì chúng sẽ không va chạm. Nếu bạn sẽ sử dụng các hàng đợi khác nhau (các luồng khác nhau) thì một đồng bộ hóa sẽ cần thiết. – Jeremy

+0

Tìm thấy nó (thông qua http://stackoverflow.com/q/10094361/480850): http://perpendiculo.us/?p=133 – Richard

Trả lời

5

Mặc dù sự khác biệt chức năng có thể không quan trọng đối với bạn, đó là những gì bạn mong đợi: nếu bạn @synchronize thì chuỗi bạn đang truy cập bị chặn cho đến khi nó có thể được thực thi độc quyền. Nếu bạn gửi đến hàng đợi công văn nối tiếp một cách không đồng bộ thì chuỗi gọi có thể tiếp tục với những thứ khác và bất cứ thứ gì bạn đang thực sự làm sẽ luôn xảy ra trên cùng một hàng đợi đã biết.

Vì vậy, chúng tương đương để đảm bảo rằng tài nguyên thứ ba chỉ được sử dụng từ một hàng đợi tại một thời điểm.

Việc gửi đi có thể là một ý tưởng hay hơn nếu, giả sử bạn có tài nguyên được truy cập bởi giao diện người dùng từ hàng đợi chính và bạn muốn thay đổi nó. Sau đó, mã giao diện người dùng của bạn không cần một cách rõ ràng để @synchronize, ẩn sự phức tạp của lược đồ luồng của bạn trong đối tượng khá tự nhiên. Công văn cũng sẽ là một ý tưởng tốt hơn nếu bạn có một diễn viên trung tâm có thể kích hoạt một số thay đổi này trên các diễn viên khác nhau; điều đó sẽ cho phép chúng hoạt động đồng thời.

Đồng bộ hóa gọn nhẹ hơn và dễ dàng hơn để gỡ lỗi từng bước. Nếu những gì bạn đang làm có xu hướng là hai hoặc ba dòng và bạn cần phải gửi nó đồng bộ sau đó nó cảm thấy như đi đến nỗ lực của việc tạo ra một hàng đợi là không có giá trị nó - đặc biệt là khi bạn xem xét các chi phí tiềm ẩn của việc tạo ra một khối và di chuyển nó lên trên đống.

+0

Cảm ơn câu trả lời chi tiết.Có vẻ như hàng đợi không đồng bộ là thứ tôi muốn sau tất cả. – livingtech

4

Trong trường hợp thứ hai, bạn sẽ chặn chuỗi cuộc gọi cho đến khi "làm việc" được thực hiện. Sử dụng hàng đợi và dispatch_async, bạn sẽ không chặn chuỗi cuộc gọi. Điều này sẽ đặc biệt quan trọng nếu bạn gọi sortArrayIntoLocalStore từ chuỗi giao diện người dùng.

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