17

Gần đây tôi đã bắt đầu một dự án mới bằng cách sử dụng tính năng đếm tham chiếu tự động (ARC).
Khi tôi giao các nội dung của một CALayer:ARC có hoạt động với các đối tượng Đồ họa chính không?

UIView* view = ... 
UIImage* image = ... 
view.layer.contents = image.CGImage 

Tôi đã nhận ra lỗi

Implicit chuyển đổi của một con trỏ kiểu phi Objective-C 'CGImageRef' thành 'id' là không được phép với ARC

Chỉ cần bỏ CGImageRef đến id ẩn lỗi, nhưng tôi đã tự hỏi liệu ARC vẫn hoạt động chính xác?

Trả lời

42

Bạn thực sự nên xem video ARC từ WWDC 2011. Chúng có sẵn trên trang web dành cho nhà phát triển và mở qua iTunes. Đặc biệt:

• Phần 323 - Giới thiệu Automatic Reference Counting

• Phần 322 - Objective-C Tiến bộ trong Depth

Ngoài ra, các ghi chú tài liệu tham khảo ARC:

https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Cả ghi chú tham chiếu và video thảo luận về Đồ họa cốt lõi (et al) và cách chúng hoạt động với ARC.

Cụ thể, nhìn vào phần gọi "Quản lý Toll-Free Bridging"

Trong nhiều ứng dụng Cocoa, bạn cần sử dụng đối tượng cốt lõi Foundation-phong cách, cho dù từ khuôn khổ Lõi Foundation bản thân (ví dụ như CFArrayRef hoặc CFMutableDictionaryRef) hoặc từ các khung công tác áp dụng các quy ước Foundation Foundation như Core Graphics (bạn có thể sử dụng các loại như CGColorSpaceRef và CGGradientRef).

Trình biên dịch không tự động quản lý thời gian tồn tại của Core Các đối tượng nền tảng; bạn phải gọi CFRetain và CFRelease (hoặc các biến thể loại tương ứng cụ thể) như được quyết định bởi các quy tắc quản lý bộ nhớ nền tảng của Foundation (xem Hướng dẫn lập trình quản lý bộ nhớ Hướng dẫn về Core Foundation).

Nếu bạn cast giữa Objective-C và Core vật Foundation-phong cách, bạn cần phải nói với trình biên dịch về ngữ nghĩa quyền sở hữu của đối tượng bằng cách sử dụng một dàn diễn viên (quy định tại objc/runtime.h) hoặc Core Macro kiểu nền tảng (được định nghĩa trong NSObject.h): [...]

Jörg Jacobsen cũng có tổng quan tóm tắt về các tùy chọn cầu nối: Managing Toll-free Bridging in an ARC’ed Environment.

__bridge_retained (n.b.: chỉ sử dụng nó khi chuyển từ đối tượng trỏ sang con trỏ kiểu C): Tôi (lập trình viên) cần tham khảo đối tượng này trong một thời gian nào đó trong thế giới tối của con trỏ loại C mờ đục tới bạn, ARC. Vì vậy, xin vui lòng, xin vui lòng không phát hành đối tượng này trong khi tôi vẫn còn cần nó. I (lập trình viên) hứa sẽ thả nó bản thân mình (trong thế giới tối tăm) khi tôi đang thực hiện với nó

__bridge_transfer (nb: chỉ sử dụng nó khi đúc từ loại C con trỏ đến đối tượng con trỏ): I (lập trình viên) giao cho bạn, ARC, một đối tượng mà tôi sở hữu và rằng tôi không còn quan tâm đến thế giới của các con trỏ loại C tối tăm mờ đục đối với bạn. Bất cứ khi nào bạn, ARC, được thực hiện với đối tượng đó, vui lòng tự giải phóng nó, vì bạn biết thời gian phù hợp và do đó, hãy tiết kiệm cho tôi một số công việc không phải tự làm.

__bridge: ARC, bạn tiếp tục cân bằng việc giữ lại và giải phóng khi tôi giữ thăng bằng trong thế giới tối của các con trỏ loại C mà là…. Bất cứ khi nào tôi cần giữ một vật trong thế giới đen tối, tôi sẽ giữ tự giữ nó và nhả nó khi thích hợp. Tôi không cần bất kỳ hợp đồng bổ sung nào với bạn, ARC.

+0

câu trả lời vô cùng hữu ích và đầy đủ, cảm ơn rất nhiều – Pieter

+0

:) Cảm ơn! Mừng vì tôi có thể giúp! Chúng tôi di chuyển một ứng dụng khá lớn, chúng tôi có một vài ngày trước và mất khoảng hai ngày để làm việc tất cả các kinks ra, nhưng tôi khá hài lòng với kết quả cuối cùng. Rất ít mã, mạnh mẽ hơn rất nhiều. ARC là khá mát mẻ. Những video đó là một tài nguyên tuyệt vời cho tôi. – Steve

+0

+1 để trích dẫn lời giải thích của Jorg Jacobsen. – jAckOdE

8

Mặc dù các tài liệu tham khảo được chỉ ra bởi Steve, tôi tin rằng trường hợp bạn hiển thị ở trên có thể đặc biệt. Từ Transitioning to ARC Release Notes, chú ý đến phần "Các biên dịch Xử lý CF đối tượng trả lại từ phương pháp Cocoa":

Trình biên dịch hiểu phương pháp Objective-C trở Lõi loại Quỹ theo các công ước Cocoa đặt tên lịch sử (xem nâng cao Hướng dẫn lập trình quản lý bộ nhớ). Ví dụ, trình biên dịch biết rằng, trong iOS, CGColor được trả về bằng phương thức CGColor của UIColor không thuộc sở hữu.

Ví dụ mã họ cung cấp:

gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor], 
               (id)[[UIColor lightGrayColor] CGColor], nil]; 

dựa vào sự trở lại được biết đến của CGColors từ những phương pháp này (họ đang thiếu các diễn viên để id mà tôi đã được thêm vào trong đoạn mã trên, mà nên sửa chữa trong tài liệu của họ sớm).

Bởi vì [image CGImage] tuân theo quy ước đặt tên, tôi tin rằng CGImage sẽ được bắc cầu đúng ở đây. Tôi nghĩ rằng diễn viên của bạn để id nên được tất cả những gì bạn cần ở đây.

4

Một câu trả lời phổ biến cho câu hỏi layer.contents = (id)image.CGImagelayer.contents = obj_unretainedObject(image.CGImage).

Tôi làm =(__bridge id)image.CGImage.

+0

Tôi khuyên bạn nên thêm định dạng mã vào câu trả lời của bạn, để cải thiện khả năng đọc. –

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