Thuộc tính theo ARC: Luôn luôn hoặc chỉ công khai?


9

Sau khi đọc một bài báo có tên khiêm tốn "Các điều răn về quy tắc: Thực tiễn tốt nhất cho mã hóa mục tiêu-C" của Robert McNally cách đây chưa đầy hai năm, tôi đã áp dụng cách sử dụng các thuộc tính cho hầu hết mọi thành viên dữ liệu của các lớp Objective-C của tôi ( điều răn thứ 3 tính đến tháng năm 2012). McNally liệt kê những lý do để làm như vậy (nhấn mạnh của tôi):

  1. Thuộc tính thi hành các hạn chế truy cập (chẳng hạn như chỉ đọc)
  2. Thuộc tính thi hành chính sách quản lý bộ nhớ (mạnh, yếu)
  3. Các thuộc tính cung cấp cơ hội để thực hiện trong suốt setters và getters tùy chỉnh.
  4. Các thuộc tính với setters hoặc getters tùy chỉnh có thể được sử dụng để thực thi chiến lược an toàn luồng.
  5. Có một cách duy nhất để truy cập các biến thể hiện làm tăng khả năng đọc mã.

Tôi đặt hầu hết các tài sản của mình trong các danh mục riêng tư, vì vậy số 1 và 4 thường không phải là vấn đề tôi gặp phải. Đối số 3 và 5 là 'mềm' hơn, và với các công cụ phù hợp và các tính nhất quán khác, chúng có thể trở thành không vấn đề. Vì vậy, cuối cùng, với tôi, người có ảnh hưởng nhất trong số các đối số này là số 2, quản lý bộ nhớ. Tôi đã làm điều này từ bao giờ.

@property (nonatomic, strong) id object; // Properties became my friends.

Đối với một vài dự án cuối cùng của tôi, tôi đã chuyển sang sử dụng ARC, điều này khiến tôi nghi ngờ liệu việc tạo các thuộc tính cho hầu hết mọi thứ vẫn là một ý tưởng hay hoặc có thể hơi thừa. ARC chăm sóc bộ nhớ quản lý các đối tượng Objective-C cho tôi, hầu hết strongcác thành viên đều hoạt động tốt nếu bạn chỉ khai báo các ivars. Các loại C bạn phải quản lý thủ công bằng mọi cách, trước và sau ARC và các weakthuộc tính chủ yếu là loại công khai.

Tất nhiên tôi vẫn sử dụng các thuộc tính cho bất cứ thứ gì cần truy cập từ bên ngoài lớp, nhưng chúng hầu hết chỉ là một số thuộc tính, trong khi hầu hết các thành viên dữ liệu được liệt kê dưới dạng ngà dưới tiêu đề triển khai

@implementation GTWeekViewController
{
    UILongPressGestureRecognizer *_pressRecognizer;
    GTPagingGestureRecognizer *_pagingRecognizer;
    UITapGestureRecognizer *_tapRecognizer;
}

Như một thử nghiệm tôi đã thực hiện việc này chặt chẽ hơn một chút và việc tránh xa các thuộc tính cho mọi thứ có một số tác dụng phụ tích cực tốt.

  1. Yêu cầu mã thành viên dữ liệu ( @property/ @synthesize) thu nhỏ lại chỉ để khai báo ivar.
  2. Hầu hết các self.somethingtài liệu tham khảo của tôi làm sạch lên chỉ _something.
  3. Thật dễ dàng phân biệt thành viên dữ liệu nào là riêng tư (ivars) và công khai (thuộc tính).
  4. Cuối cùng, "cảm giác" giống như đây là mục đích mà Apple dành cho các mục đích, nhưng đó là suy đoán chủ quan.

Đối với câu hỏi : Tôi đang dần trượt về phía bóng tối, sử dụng các thuộc tính ngày càng ít hơn để ủng hộ việc triển khai. Bạn có thể cung cấp cho tôi một chút lý do tại sao tôi nên sử dụng các thuộc tính cho tất cả mọi thứ, hoặc xác nhận dòng suy nghĩ hiện tại của tôi về lý do tại sao tôi nên sử dụng nhiều ngà hơn và ít tài sản hơn khi cần thiết? Câu trả lời thuyết phục nhất cho cả hai bên sẽ nhận được điểm của tôi.

EDIT: McNally cân nhắc trên Twitter, nói : "Tôi nghĩ lý do chính của tôi để gắn bó với tài sản là: một cách để làm mọi thứ, đó là làm mọi thứ (bao gồm KVC / KVO.)"

Câu trả lời:


5

Bạn có thể cung cấp cho tôi một chút lý do tại sao tôi nên sử dụng các thuộc tính cho tất cả mọi thứ, hoặc xác nhận dòng suy nghĩ hiện tại của tôi về lý do tại sao tôi nên sử dụng nhiều ngà hơn và ít tài sản hơn khi cần thiết?

Ngay bây giờ, tôi nghĩ thật công bằng khi nói rằng đó chủ yếu là vấn đề về phong cách. Như bạn nói, lợi ích quản lý bộ nhớ của các thuộc tính ít quan trọng hơn với ARC. Mặt khác, "lợi ích" của việc quay trở lại truy cập ngà trực tiếp cũng không hấp dẫn lắm:

  1. Một khai báo @property khá giống với khai báo ivar. Tránh chỉ thị @synthesize dường như không phải là một chiến thắng lớn - chúng tôi không nói về nhiều mã.

  2. Các foo.somethingcú pháp được cho là tốt hơn rất nhiều so với _something. Cú pháp truy cập thuộc tính rõ ràng được thiết kế để trông giống và hoạt động như cú pháp dấu chấm của C để truy cập các thành viên của cấu trúc. Rõ ràng về đối tượng bạn đang truy cập (cho dù đó selfhoặc một cái gì khác) là hữu ích. (Một số người - không phải tôi! - ủng hộ self->somethingviệc truy cập bằng ngà vì lý do này.) Quy ước gạch dưới hàng đầu cho ngà là tốt, nhưng nó không được sử dụng nhất quán bởi tất cả mã Objective-C.

  3. Các thuộc tính có vẻ là lựa chọn tốt hơn để truy cập dữ liệu được lưu trữ trong các đối tượng khác cùng lớp (được phép truy cập "riêng tư") và để truy cập bởi các lớp con (như "được bảo vệ" của C ++). Vì vậy, ý tưởng 'property == public' có phần mờ nhạt.

  4. Ý thức của tôi là các thuộc tính được dự định để đơn giản hóa việc quản lý bộ nhớ và cung cấp một số lợi ích khác. Như bạn nói, với lợi ích quản lý bộ nhớ giảm, các thuộc tính dường như ít hấp dẫn hơn.

Con đường bạn đã chọn - quay trở lại truy cập ivar trực tiếp cho dữ liệu nội bộ - có vẻ như là một lựa chọn rất hợp lý và không có lý do rõ ràng để thay đổi khóa học của bạn. Nhưng việc gắn bó với các thuộc tính cũng khá hợp lý - những hạn chế không đáng kể và có một số lợi ích tốt như tuân thủ KVO và phong cách truy cập thành viên nhất quán hơn.

Các thuộc tính không phải là bước cuối cùng trong quá trình phát triển của Objective-C và tôi không hy vọng rằng ARC cũng sẽ như vậy. Tôi không có bất kỳ thông tin cụ thể nào, nhưng có vẻ như một dự đoán tốt rằng các tính năng bổ sung có thể được thêm vào một số điểm khiến các thuộc tính trở nên hấp dẫn hơn hoặc ít hơn. Chúng ta sẽ phải chờ xem điều gì sẽ xảy ra.


1
Xin chào @Caleb, cảm ơn bạn đã dành thời gian và viết một bài đăng vững chắc. Tôi đã không nghĩ về khía cạnh KVO. Tôi thực sự rất tò mò về nơi Apple sẽ lấy tất cả những thứ này. ARC như là một trong một loạt các bước. Tôi sẽ chờ xem liệu có ai khác quan tâm đến vấn đề này không, nếu không hãy xem xét việc kiểm tra câu hỏi được đánh dấu.
epologee

1
@epologee Vui mừng khi được giúp đỡ. Thêm một mục để thêm vào cột cộng cho ivars là bạn có thể thấy chúng dễ dàng trong trình gỡ lỗi. Điều đó cũng đúng với các thuộc tính, nếu bạn tuyên bố rõ ràng ngà mà tài sản sử dụng. Ivars tổng hợp không xuất hiện trong trình gỡ lỗi. (Tôi sẽ không ngạc nhiên khi thấy sự thay đổi đó một ngày nào đó sớm thôi.)
Caleb

-1

Tôi cũng đã suy nghĩ về câu hỏi này. Theo ý kiến ​​khiêm tốn của tôi, chỉ sử dụng các thuộc tính cho người truy cập làm cho mã dễ đọc hơn nhiều. Bạn có thể thấy ngay những biến nào có nghĩa là được truy cập công khai. Và cá nhân, luôn luôn gõ @property (...) trước một biến là tốn thời gian.


Xin chào Alex, tôi nghĩ rằng bạn tốt hơn nên trả lời các câu hỏi gần đây hơn trên SE. Tôi không đồng ý nhiều với tranh luận tốn thời gian. Tôi không viết mã giúp tôi tiết kiệm thời gian bằng văn bản, tôi thích viết mã giúp tiết kiệm tương lai của tôi hoặc người khác có thời gian để hiểu nó. Điều đó nói rằng, phiếu bầu -1 không phải là của tôi. Sẽ tốt đẹp cho người đó để làm rõ phiếu bầu.
epologee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.