Không có nhược điểm. Sử dụng nó. Làm nó ngay hôm nay. Nó nhanh hơn mã cũ của bạn. Nó an toàn hơn mã cũ của bạn. Nó dễ dàng hơn mã cũ của bạn. Nó không phải là thu gom rác. Nó không có chi phí thời gian chạy GC. Trình biên dịch chèn giữ lại và phát hành ở tất cả những nơi bạn nên có. Nhưng nó thông minh hơn bạn và có thể tối ưu hóa những thứ không thực sự cần thiết (giống như nó có thể mở vòng lặp, loại bỏ các biến tạm thời, hàm nội tuyến, v.v.)
OK, bây giờ tôi sẽ cho bạn biết về những nhược điểm nhỏ:
Nếu bạn là nhà phát triển ObjC lâu năm, bạn sẽ giật mình trong khoảng một tuần khi nhìn thấy mã ARC. Bạn sẽ rất nhanh chóng vượt qua điều này.
Có một số (rất) phức tạp nhỏ trong việc bắc cầu với mã Core Foundation. Có một chút phức tạp hơn trong việc xử lý bất cứ thứ gì coi id
là một void*
. Những thứ như mảng C id
có thể mất thêm một chút suy nghĩ để thực hiện chính xác. Việc xử lý lạ mắt đối với ObjC va_args
cũng có thể gây ra rắc rối. Hầu hết những thứ liên quan đến toán học trên con trỏ objC phức tạp hơn. Bạn không nên có nhiều thứ này trong mọi trường hợp.
Bạn không thể đặt một id
trong một struct
. Điều này khá hiếm, nhưng đôi khi nó được sử dụng để đóng gói dữ liệu.
Nếu bạn không tuân theo cách đặt tên KVC chính xác và trộn lẫn mã ARC và mã không phải ARC, bạn sẽ gặp sự cố về bộ nhớ. ARC sử dụng cách đặt tên KVC để đưa ra quyết định về quản lý bộ nhớ. Nếu tất cả đều là mã ARC, thì không vấn đề gì vì nó sẽ làm như nhau "sai" ở cả hai bên. Nhưng nếu đó là ARC hỗn hợp / không phải ARC thì sẽ có sự không phù hợp.
ARC sẽ làm rò rỉ bộ nhớ trong quá trình ném ngoại lệ ObjC. Một ngoại lệ của ObjC sẽ rất gần với thời điểm chấm dứt chương trình của bạn. Nếu bạn đang gặp phải một số lượng đáng kể các ngoại lệ objC, thì bạn đang sử dụng chúng không đúng cách. Điều này có thể sửa được bằng cách sử dụng -fobjc-arc-exceptions
, nhưng nó phải chịu các hình phạt được thảo luận bên dưới:
ARC sẽ không làm rò rỉ bộ nhớ trong khi ném ngoại lệ ObjC hoặc C ++ trong mã ObjC ++, nhưng điều này phải trả giá bằng cả hiệu suất thời gian và không gian. Đây là một lý do khác trong danh sách dài các lý do để giảm thiểu việc sử dụng ObjC ++.
ARC sẽ hoàn toàn không hoạt động trên iPhoneOS 3 hoặc Mac OS X 10.5 trở xuống. (Điều này ngăn cản tôi sử dụng ARC trong nhiều dự án.)
__weak
Con trỏ không hoạt động chính xác trên iOS 4 hoặc Mac OS X 10.6, điều này thật đáng tiếc, nhưng khá dễ dàng để khắc phục. __weak
con trỏ rất tuyệt, nhưng chúng không phải là điểm bán hàng số 1 của ARC.
Đối với hơn 95% mã ngoài đó, ARC là tuyệt vời và không có lý do gì để tránh nó (miễn là bạn có thể xử lý các hạn chế về phiên bản hệ điều hành). Đối với mã không phải ARC, bạn có thể chuyển -fno-objc-arc
trên cơ sở từng tệp. Xcode không may làm cho việc này khó hơn nhiều so với thực tế. Bạn có thể nên chuyển mã không phải ARC vào một xcodeproj riêng biệt để đơn giản hóa việc này.
Tóm lại, hãy chuyển sang ARC ngay khi bạn có thể và không bao giờ nhìn lại.
BIÊN TẬP
Tôi đã thấy một vài nhận xét dọc theo dòng "sử dụng ARC không thể thay thế cho việc biết các quy tắc quản lý bộ nhớ Cocoa." Điều này hầu hết đúng, nhưng điều quan trọng là phải hiểu tại sao và tại sao không. Đầu tiên, nếu tất cả mã của bạn sử dụng ARC và bạn vi phạm Ba Phép thuậtở khắp nơi, bạn vẫn sẽ không gặp vấn đề gì. Nói thật là sốc, nhưng bạn hiểu rồi. ARC có thể giữ lại một số thứ mà bạn không muốn giữ lại, nhưng nó cũng sẽ giải phóng chúng, vì vậy điều đó sẽ không bao giờ thành vấn đề. Nếu hôm nay tôi đang dạy một lớp mới ở Cocoa, có lẽ tôi sẽ dành không quá năm phút cho các quy tắc quản lý bộ nhớ thực tế và có lẽ tôi sẽ chỉ đề cập đến các quy tắc đặt tên quản lý bộ nhớ trong khi thảo luận về việc đặt tên KVC. Với ARC, tôi tin rằng bạn thực sự có thể trở thành một lập trình viên mới bắt đầu tốt mà không cần học các quy tắc quản lý bộ nhớ.
Nhưng bạn không thể trở thành một lập trình viên trung cấp tốt. Bạn cần biết các quy tắc để kết nối chính xác với Core Foundation và mọi lập trình viên trung cấp cần phải đối phó với CF tại một số điểm. Và bạn cần biết các quy tắc cho mã hỗn hợp ARC / MRC. Và bạn cần biết các quy tắc khi bạn bắt đầu lộn xộn với các void*
con trỏ tới id
(mà bạn tiếp tục cần thực hiện KVO một cách chính xác). Và khối ... tốt, quản lý bộ nhớ khối thật kỳ lạ.
Vì vậy, quan điểm của tôi là việc quản lý bộ nhớ cơ bản vẫn quan trọng, nhưng nơi tôi đã từng dành thời gian đáng kể để nêu và đặt lại các quy tắc cho các lập trình viên mới, với ARC, nó đang trở thành một chủ đề nâng cao hơn. Tôi muốn các nhà phát triển mới suy nghĩ về đồ thị đối tượng hơn là lấp đầy đầu họ bằng những lời gọi cơ bản tới objc_retain()
.