2013-04-01 15 views
8

Tôi có kinh nghiệm về mã hóa ARC thuần túy. Là một tính năng của trình biên dịch, nó tôn vinh gia đình phương thức Objctive-C đặt quyền giữ lại/phát hành cuộc gọi bất cứ khi nào neeeded.Quy ước đặt tên mục tiêu-C với ARC và các cảnh báo có thể xảy ra

Tất cả các phương pháp bắt đầu bằng alloc, mutableCopy, copynew tạo đối tượng mới. Họ tăng số lượng giữ lại. Kết quả là, ARC sẽ giải phóng bất kỳ con trỏ nào (và do đó đối tượng được liên kết với nó) khi tôi không còn cần đến nó nữa.

Tôi nghĩ rằng các vấn đề có thể phát sinh khi tôi viết các phương thức không tuân theo quy ước đặt tên. Ví dụ, nếu tôi viết một phương thức như newCustomer rằng trong phiên bản đầu tiên trả về một đối tượng tự động phát hành trong khi ở phiên bản thứ hai thì không, điều gì có thể xảy ra?

Đặc biệt, câu hỏi của tôi là như sau (họ thuộc về các lập luận tương tự):

  • gì xảy ra nếu sự kêu gọi và được gọi là mã được cả biên soạn với ARC?
  • (a) Điều gì sẽ xảy ra nếu mã gọi được biên dịch với ARC trong khi được gọi là được biên dịch với không phải ARC?
  • (b) Điều gì sẽ xảy ra nếu mã gọi được biên dịch với không phải ARC trong khi được gọi là được biên dịch với ARC?

Nó sẽ được đánh giá cao một câu trả lời cho thấy cách ARC hoạt động dưới mui xe (objc_release, objc_retainAutoreleasedReturnValue, v.v.).

Cảm ơn bạn trước.

+0

'mới' với Mục tiêu-C? –

+0

@ ott-- Xin lỗi, ý của bạn là gì? Cảm ơn. –

+1

1) Đừng làm điều đó. 2) Nếu bạn bỏ qua (1), tôi nghĩ * có một số sửa đổi gạch dưới cho khai báo phương thức có thể được sử dụng để vá mọi thứ. –

Trả lời

12

Phương pháp có tên newCustomer sẽ nằm trong số newmethod family và do đó được đánh dấu hoàn toàn là trả lại đối tượng được giữ lại. Khi cả hai gọi điện thoại và gọi là mã được biên soạn với ARC, sau đó ARC cân bằng phụ giữ lại với một thông cáo trong người gọi:

khi trở về từ một hàm hoặc phương pháp như vậy, ARC vẫn giữ được giá trị tại thời điểm đánh giá báo cáo trả lại, trước khi rời khỏi tất cả phạm vi địa phương.

Khi nhận được kết quả trả về từ hàm hoặc phương thức như vậy, ARC giải phóng giá trị ở cuối biểu thức đầy đủ chứa bên trong, tùy thuộc vào việc tối ưu hóa thông thường cho giá trị cục bộ.

Source

Nếu newCustomer được thực hiện bằng tay tính tham khảo và vi phạm quy ước đặt tên (ví dụ, không trả lại một đối tượng giữ lại), sau đó người gọi có thể qua phát hành hoặc theo phát hành, tùy theo hoàn cảnh .

Nếu người gọi sử dụng ARC, thì đối tượng được trả lại từ newCustomer sẽ bị quá tải - có khả năng khiến chương trình gặp sự cố. Điều này là do mã gọi điện thoại sẽ tham gia vào nửa sau của quá trình trên, mà không cần phải có một khoản giữ lại tương ứng được thực hiện trước đó.

Nếu mã gọi không được biên dịch với ARC, nhưng mã được gọi là (do đó thực hiện đúng đối tượng được giữ lại), thì hành vi phụ thuộc vào lập trình viên tuân theo quy ước đặt tên. Nếu chúng giải phóng giá trị trả lại, thì số lượng tham chiếu của đối tượng sẽ được quản lý một cách chính xác. Tuy nhiên, nếu lập trình viên tin rằng phương thức new... của họ vi phạm quy ước đặt tên và không chèn thủ công bản phát hành vào mã gọi, thì đối tượng được trả lại sẽ bị rò rỉ.

Tất cả trong tất cả, như Martin R. chỉ ra trong các nhận xét, xác định quan trọng là liệu các quy ước đặt tên có được tuân thủ trong bất kỳ môi trường nào kể cả tính toán tham khảo thủ công hay không.

+1

Tôi sẽ xây dựng phần thứ hai hơi khác nhau (câu trả lời của bạn xuất hiện trước khi tôi đã hoàn thành của tôi :-). Trong chế độ hỗn hợp, nếu mã không phải ARC tuân thủ các quy ước đặt tên thì mọi thứ đều OK, nếu không bạn có quá nhiều hoặc ít phát hành. - Trong nhiều tình huống, máy phân tích tĩnh phát hiện các lỗi này. –

+0

Có, tôi đã giải quyết cụ thể trường hợp newCustomer trả về một đối tượng không được giữ lại. Xin lỗi nếu tôi không nói rõ. –

+1

Hơn nữa, nó sẽ là * rất * xấu để có một lớp con/siêu lớp trong đó một phương thức đã cho trong một lớp trả về một đối tượng được giữ lại trong khi cùng một phương thức trong lớp kia thì không. –

2

Cũng giống như bất kỳ ngôn ngữ nào khác, khi bạn vi phạm một số giả định cơ bản về ngôn ngữ bạn đi lang thang vào khu vực của hành vi không xác định. Tại một số thời điểm trong tương lai, Apple có thể sửa đổi nội bộ của cách thức -new... tính tham chiếu. Điều này tùy thuộc vào Apple để đảm bảo rằng mã phù hợp với các công việc sử dụng dự kiến, nhưng chúng sẽ không làm điều đó cho các mục đích không phù hợp.

Nếu bạn cần biết hành vi thực tế là gì đối với phiên bản trình biên dịch cụ thể đang chạy trên một hệ thống cụ thể, thì bạn phải kiểm tra nó. Đừng cho rằng hành vi sẽ giống nhau đối với các trình biên dịch hoặc phiên bản khác của thời gian chạy.

Cuối cùng, hành vi không xác định là hành vi không xác định. Khi bạn xây dựng mã dựa vào nó, cuối cùng bạn sẽ bị ảnh hưởng bởi một khiếm khuyết tinh tế và khó chẩn đoán.

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