36

Tôi duy trì hàng đợi công văn là thuộc tính với bộ điều khiển chế độ xem của tôi. Tôi tạo hàng đợi này một lần trong phương thức init của trình điều khiển xem của tôi và sử dụng lại một vài lần cho một số tác vụ nền. Trước ARC, tôi đã làm điều này:Tôi nên sử dụng thuộc tính nào cho một Hàng đợi Công văn sau ARC?

@property (nonatomic, assign) dispatch_queue_t filterMainQueue; 

Và trong init:

if (filterMainQueue == nil) { 
    filterMainQueue = dispatch_queue_create("com.myQueue.CJFilterMainQueue", NULL); 
} 

Nhưng sau ARC, tôi không chắc chắn nếu điều này vẫn cần được "gán", hoặc nó phải được "mạnh mẽ "hoặc" yếu ". Kịch bản chuyển đổi ARC không thay đổi bất cứ điều gì nhưng tôi không chắc chắn nếu một lỗi tinh tế đến từ thực tế là hàng đợi này có thể được deallocated trong khi nó đang được sử dụng?

Điều gì sẽ là sự khác biệt giữa 3 loại thuộc tính và điều gì sẽ phù hợp nhất với hàng đợi công văn khi sử dụng ARC?

Trả lời

55

Câu trả lời được cập nhật:

Trong OS X và iOS hiện tại, Các đối tượng gửi hiện được xử lý dưới dạng đối tượng Obj-C theo ARC. Họ sẽ được quản lý bộ nhớ giống như cách đối tượng Obj-C sẽ, và bạn nên sử dụng strong cho tài sản của bạn.

Điều này được điều khiển bởi macro OS_OBJECT_USE_OBJC, được xác định trong <os/object.h>. Nó được đặt thành 1 theo mặc định khi mục tiêu triển khai của bạn là OS X 10.8 trở lên hoặc iOS 6.0 trở lên. Nếu bạn đang triển khai cho một hệ điều hành cũ hơn, thì điều này được để lại tại 0 và bạn sẽ thấy câu trả lời ban đầu của tôi bên dưới.


Original câu trả lời:

đối tượng văn (bao gồm cả hàng đợi) không phải là đối tượng obj-C, vì vậy sự lựa chọn duy nhất có thể là assign. Trình biên dịch sẽ ném một lỗi nếu bạn cố gắng sử dụng strong hoặc weak. ARC không ảnh hưởng đến GCD.

+0

@JimThio: [Grand Central Dispatch] (http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html) –

+13

Điều này không còn đúng trong Mountain Lion - xem /usr/include/os/object.h. GCD và XPC "đối tượng" (bất cứ điều gì bạn có thể phát hành rõ ràng) bây giờ cư xử đủ giống như các đối tượng ObjC mà họ có thể tham gia vào ARC. – jkh

+0

@jkh cũng bao gồm nền tảng iOS? – Ankur

4

Dưới đây là những gì tôi sử dụng:

@property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue; 
+0

Tại sao? Bạn co thể giải thich không? –

+2

Về cơ bản, nó biến một đối tượng không phải ObjC thành một thuộc tính ObjC để bạn có thể dễ dàng sử dụng nó như self.queue – Arvin

+0

@Arvin Điều gì đó đã thay đổi với 6.1 ảnh hưởng đến điều này. Nó phàn nàn về __attribute__ và loại bỏ nó dường như làm việc ngay bây giờ. Tôi đã không chạy vào bất kỳ vấn đề vì vậy tôi đoán tài sản (readwrite, mạnh mẽ, nonatomic) dispatch_queue_t hàng đợi là an toàn? – TheJer

4

Dựa trên iOS7, tôi đã kiểm tra liệu dispatch_queue đối tượng là một đối tượng mục tiêu-C và tôi đã tìm ra họ đã là mục tiêu-c đối tượng. để diễn giải điều này, thuộc tính ((NSObject)) là không cần thiết ngay bây giờ.

1

TL; DR: dispatch_queue_t là đối tượng C mục tiêu bây giờ và có thể được quản lý với ARC.

Tôi chưa thử nghiệm điều này đúng như thế nào, nhưng sử dụng SDK iOS 7 và Xcode 5, dispatch_queue_t là loại đối tượng. Tôi tuyên bố một thuộc tính cho hàng đợi là

@property (nonatomic, strong) dispatch_queue_t syncQueue; 

Trình biên dịch vui vẻ và mọi thứ hoạt động như mong đợi. Tôi biết dứt khoát rằng điều này được sử dụng để không hoạt động trong iOS 4 hoặc 5 (trước ARC là retain thay vì strong).Tôi đào vào định nghĩa cho dispatch_queue_t và thấy điều này:

/*! 
* @typedef dispatch_queue_t 
* 
* @abstract 
* Dispatch queues invoke blocks submitted to them serially in FIFO order. A 
* queue will only invoke one block at a time, but independent queues may each 
* invoke their blocks concurrently with respect to each other. 
* 
* @discussion 
* Dispatch queues are lightweight objects to which blocks may be submitted. 
* The system manages a pool of threads which process dispatch queues and 
* invoke blocks submitted to them. 
* 
* Conceptually a dispatch queue may have its own thread of execution, and 
* interaction between queues is highly asynchronous. 
* 
* Dispatch queues are reference counted via calls to dispatch_retain() and 
* dispatch_release(). Pending blocks submitted to a queue also hold a 
* reference to the queue until they have finished. Once all references to a 
* queue have been released, the queue will be deallocated by the system. 
*/ 
DISPATCH_DECL(dispatch_queue); 

Bằng những âm thanh đó, nó không nên làm việc, vì vậy tôi đã kiểm tra các định nghĩa của DISPATCH_DECL và thấy điều này, điều này giải thích tất cả mọi thứ:

/* 
* By default, dispatch objects are declared as Objective-C types when building 
* with an Objective-C compiler. This allows them to participate in ARC, in RR 
* management by the Blocks runtime and in leaks checking by the static 
* analyzer, and enables them to be added to Cocoa collections. 
* See <os/object.h> for details. 
*/ 
7

sau đây là cách người ta sẽ xác định tài sản dispatch_queue_t cho iOS 6.0 trở lên và dưới iOS 6,0

#if OS_OBJECT_HAVE_OBJC_SUPPORT == 1 
@property (nonatomic, strong) dispatch_queue_t serialDispatchQueue; 
#else 
@property (nonatomic, assign) dispatch_queue_t serialDispatchQueue; 
#endif 

về cơ bản OS_OBJECT_HAVE_OBJC_SUPPORT i s được định nghĩa là 1 cho iOS 6.0 trở lên. (MAC 10.8 trở lên). Dưới iOS 6, nó được định nghĩa là 0.

OS_OBJECT_HAVE_OBJC_SUPPORT xác định rằng các đối tượng OS như GCD có hỗ trợ C mục tiêu. Vì vậy, ARC, quản lý bộ nhớ, tính tham chiếu vv áp dụng cho các đối tượng GCD.

+1

Điều này bằng cách nào đó không thành công cho các thư viện CocoaPods http://stackoverflow.com/q/27267865/1049134 – Rivera

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