6

Tôi đang viết mã nhằm làm việc cả dưới ARC và dưới Bộ sưu tập rác.Chế độ kép ARC/GC và Core Foundation cầu nối

Dưới đây là một chút mã mà sử dụng lõi Quỹ vì nó có thể được viết riêng cho ARC:

CFTypeRef ref=CFCopySomething(); 
// At this point ref has retain count 1. 
id obj=(__bridge_transfer id)ref; 
// Ref still has retain count 1 but is now managed by ARC. 
[obj doSomething]; 
// ARC will release ref when done. 

Có vẻ như đây là tương đương với:

CFTypeRef ref=CFCopySomething(); 
// At this point ref has retain count 1. 
id obj=(__bridge id)ref; 
// Now ref has retain count 2 due to assigning to strong variable under ARC. 
CFRelease(ref) 
// Now ref has retain count 1. 
[obj doSomething]; 
// ARC will release ref when done. 

Lợi ích của con người sau đó cuộc gọi CFRelease cho phép GC thu thập đối tượng. Nhưng tôi không chắc chắn về việc gọi CFRelease sau khi chuyển sang ARC với nhiệm vụ chuyển nhượng cầu.

Có vẻ như nó hoạt động. Mã này có OK không?

+1

Điều đáng nói đến với người đọc là phôi '__bridge' không có ý nghĩa đối với các đơn vị biên dịch không phải ARC, nghĩa là trình biên dịch sẽ đơn giản bỏ qua chúng khi biên dịch bằng' --objc-gc', làm cho đoạn mã thứ 2 của bạn tương thích với cả ARC và GC. (Chỉ cần nói rằng tôi phải tìm kiếm.) – paulotorrens

Trả lời

2

Đoạn mã thứ hai của bạn là chính xác và thực sự là cách tốt nhất để xử lý cả ARC và GC. Bạn cũng có thể sử dụng CFMakeCollectable khi tạo đối tượng, và sau đó có CFRelease thực hiện như sau:

if ([NSGarbageCollector defaultCollector] == NULL) CFRelease (myCFString)

Nhưng tôi thích rõ hơn những gì bạn có với chỉ một cuộc gọi hoạt động cho cả hai môi trường.

1

Nick,

Vì CFObject không được ARC xử lý, bạn có thể thực sự muốn giữ mã được quản lý theo cách thủ công tại đây. ARC thực sự tập trung vào Cocoa chứ không phải Core Foundation. Điều đó nói rằng, bạn nói mã hoạt động nhưng nó bị rò rỉ? Hãy nhớ rằng mã ARC có cờ trình biên dịch không đúng do bị rò rỉ. Trong tài liệu Apple này, họ cho rằng ARC không quản lý các đối tượng CF: https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html. Do đó, tôi nghĩ mã __bridge của bạn bị rò rỉ và đang chờ xác nhận hoặc từ chối của bạn từ công cụ rò rỉ của Công cụ.

Andrew

+1

Tôi có thể xác nhận rằng mã không bị rò rỉ khi được biên dịch trong ARC. –

+0

Nick, OK, tôi rất vui vì bạn đã xác nhận điều đó. Đối với câu hỏi GC của bạn, vì CFRelease của bạn có thể xảy ra ở bất cứ nơi nào sau lần sử dụng cuối cùng của bạn, tại sao bạn lại đặt nó trước lần sử dụng cuối cùng và hy vọng ARC/GC sắp xếp nó ra? Nếu bạn chỉ cần dính vào mẫu chuẩn cho các đối tượng CF, thì bạn không cần phải suy nghĩ về các vấn đề ARC v GC. IOW, trong khối thứ hai của bạn, di chuyển CFRelease đến điểm cuối cùng bạn cần mục. ARC và GC sẽ không thông minh hơn nhiều so với bạn. (BTW, tôi nghĩ chuyển nhượng cầu nối của bạn không làm gì ngoài thay đổi tên. Không có ngữ nghĩa phân bổ nào được thay đổi.) Andrew – adonoho

+1

Theo GC, CFRelease được yêu cầu đánh dấu một đối tượng CF là thu. Nó là thông thường để làm điều này tại thời điểm tạo ra (thường sử dụng CF/NSMakeCollectable, nhưng CFRelease cũng hoạt động tốt). Tương tự như vậy, với ARC tôi muốn bàn giao đối tượng cho ARC càng sớm càng tốt. Tất cả đều thực sự hiệu quả. –