2009-11-21 27 views
27

Tôi có một khối mã được truy cập thường xuyên và từ luồng chính hoặc một số luồng nền khác. Tôi cần đảm bảo rằng mã này chỉ được xử lý một lần.@synchronized() và sự khác biệt của NSLock

Tôi hiện đang sử dụng khối @synchronized(self) { } nhưng tôi không chắc chắn liệu đó có cung cấp sự bảo vệ chính xác hay không. Nó khác với cá thể NSLock như thế nào?

Cuối cùng, bất kỳ ai cũng có thể đề xuất cách tôi có thể bảo vệ phương pháp của mình không? Phương pháp này là trong đại biểu ứng dụng của tôi, và tôi truy cập nó từ chủ đề khác nhau bằng cách gọi:

[[[UIApplication sharedApplication] delegate] myMethod]; 

Rất cám ơn,

Mike

Trả lời

30

Có một Blog bài tuyệt vời trên blog của Google Mac về hoạt động bên trong của @synchronized:
http://googlemac.blogspot.com/2006/10/synchronized-swimming.html

tôi hiện đang sử dụng một @synchro khối nized (self) {} nhưng tôi không chắc chắn liệu đó có cung cấp bảo vệ chính xác hay không. Làm thế nào nó khác nhau từ một cá thể NSLock?

Có một số cách để đồng bộ hóa các phần quan trọng (@synchronized, NSLock, OSSpinLock, ...).
Tôi nghĩ rằng @synchronized là cách tiếp cận thuận tiện nhất (and also the slowest).
Here is a good SO answer giải thích sự khác biệt giữa @synchronized và NSLock.

Bạn đang truy cập phương thức của mình thông qua đại diện được chia sẻ (về cơ bản là một singleton). Có thể bạn có thể suy nghĩ lại về thiết kế của mình và tìm ra cách cho phép bạn khóa một đoạn mã nhỏ hơn trong phạm vi myMethod.

+0

Cảm ơn sự giúp đỡ của bạn! Có đúng không khi nào sử dụng 'self'? Tự trong trường hợp này sẽ trỏ đến ứng dụng đại biểu, không có vấn đề gì đang gọi nó? Tôi đang bối rối là tại sao bạn phải vượt qua một cái gì đó vào nó! –

+2

Bạn sử dụng (self) nếu bạn muốn khóa "per instance" và [YourClass class] nếu bạn muốn khóa "per class". (self) có nghĩa là việc thực thi phần quan trọng cần được đồng bộ hóa cho đối tượng hiện tại (cụ thể). –

+0

Ahhh, tôi hiểu rồi! Cảm ơn bao giờ hết :-) –

16

Nếu bạn thực sự có điều gì đó mà bạn muốn được xử lý một mục tại một thời điểm, đề xuất của tôi là sử dụng NSOperations và NSOperationQueue nơi bạn đã đặt maxConcurrentOperationCount thành 1. Nếu bạn đảm bảo rằng cách duy nhất khối mã được chia sẻ này được truy cập là thông qua các hoạt động trong hàng đợi này, bạn sẽ bỏ đi với nhu cầu về các khóa đắt tiền.

Điều này có thể yêu cầu sắp xếp lại một chút ứng dụng của bạn, nhưng tôi thấy rằng việc áp dụng điều này trong các ứng dụng của riêng tôi đã dẫn đến hiệu suất tốt hơn và mã sạch hơn.

+0

+1, tuy nhiên người ta phải nhận ra rằng 'tổ chức lại ít' sẽ yêu cầu mã của bạn phải hoàn toàn không đồng bộ trong tự nhiên. @synchronized có nghĩa là một khóa chặn đồng bộ, trong khi sử dụng hàng đợi có nghĩa là trang web gọi không nên mong đợi giá trị trả lại mà thay vào đó sử dụng chặn cuộc gọi để xử lý kết quả. Điều này có thể không lý tưởng trong các phần quan trọng trong mã của bạn, nơi các cuộc gọi chặn được mong đợi. – strangetimes

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