2011-01-29 16 views
29

Bạn có biết cách làm cho một thuộc tính chỉ đọc cho các cuộc gọi bên ngoài và ghi đè cho các cuộc gọi bên trong không?Mục tiêu-C: (thuộc tính cá nhân/công cộng) làm cho một thuộc tính chỉ đọc cho các cuộc gọi ngoài lớp và ghi đè cho các cuộc gọi tự gọi

Tôi đã đọc lần trước somthing mà có vẻ như

Trong .h

@property(nonatomic, readonly) NSDate* theDate; 

Trong .m

@interface TheClassName() 
@property(nonatomic, retain) NSDate* theDate; 
@end 

nhưng điều này đặt ra một cảnh báo khi biên soạn các .m "Thuộc tính theDate thuộc tính trong lớp tiếp tục lớp TheClassName không khớp với thuộc tính lớp TheClassName".

Dù sao, có vẻ như nó hoạt động (có thể đọc nhưng không được đặt từ bên ngoài lớp học, có thể làm cả từ bên trong) nhưng tôi nên bỏ lỡ một số thứ để tránh cảnh báo. Hoặc nếu bạn biết cách tốt hơn để làm điều này ...

Trả lời

62

Trong .h của bạn:

@property(nonatomic, retain, readonly) NSDate* theDate; 

Trong .m của bạn:

@interface TheClassName() 
@property(nonatomic, retain, readwrite) NSDate* theDate; 
@end 
+0

+1, cũng có thể muốn thả 'readwrite' là 'readwrite' mặc định và' nonatomic' cho đến khi điều đó thực sự cần thiết? – zoul

+4

'readwrite' làm cho nó rõ ràng rằng bạn biết chính xác những gì bạn muốn. Một số người đang thực hiện câu thần chú "luôn luôn sử dụng" nonatomic "" từ iOS đến Cocoa (tôi chắc chắn làm); nó có thể là một chính sách rộng lớn của dự án. – bbum

+1

Ngoài ra; lý do tại sao 'giữ lại' phải được đề cập ở cả hai nơi là codegen cho' @ tổng hợp' của getter của 'retain' và' assign' có thể khác nhau trong một số trường hợp nhất định. Do đó, chính sách 'giữ lại' trên chế độ xem chỉ đọc của thuộc tính * là * một phần của API/hợp đồng của lớp. – bbum

-2

Trong .m, bạn không nên đặt @property một lần nữa. Tôi không chắc chắn những gì có hiệu lực có, mặc dù. Ý của bạn là sử dụng @synthesize?

Lưu ý rằng theDate sẽ được đọc/ghi bên trong lớp thực hiện anyway, bất kể là chỉ đọc cho thế giới bên ngoài.

+1

anh ấy đang sử dụng tiện ích mở rộng lớp học. điều này có thể được sử dụng cho các thuộc tính riêng tư, mà chỉ có thể được gọi trên 'tự' http://stackoverflow.com/questions/4464112/best-practice-for-condensing-code/4465573#4465573 – vikingosegundo

+0

Nó không rõ ràng nếu đó là những gì Oliver đang cố gắng đạt được, nhưng nếu có, thì đó là một câu trả lời hay. Vikingosegundo, bạn nên đặt câu trả lời đó và Oliver có thể chấp nhận nó! – Dave

+2

anh ta đang hỏi, làm thế nào để đạt được một tài sản chỉ đọc công khai, trong khi có một tài sản riêng khác có quyền truy cập đọc-ghi. Tôi chưa bao giờ làm một điều như vậy. Tôi chỉ giải thích cho bạn, rằng anh ấy đang sử dụng một phần mở rộng lớp học, nhưng nó không trả lời câu hỏi. – vikingosegundo

-1

Nếu tài sản được hỗ trợ bởi một biến, biến được đọc-ghi từ bên trong lớp được mặc định. Làm cho tài sản chỉ đọc, và mục tiêu thiết kế của bạn sẽ được đáp ứng. Bên trong lớp học, tham khảo biến mà không cần thêm self..

+4

-1: Có nhiều lý do rất tốt để sử dụng accessors ngay cả khi tham chiếu các biến cá thể của riêng mình. (Quản lý bộ nhớ là một.) Câu hỏi của Oliver là hợp lệ. – andyvn22

3

Vấn đề này phần lớn bị loại bỏ nếu bạn chuyển sang ARC. Thay vì hai khai báo thuộc tính, bạn khai báo nó một lần trong tiêu đề.

@property(nonatomic, readonly) NSDate* theDate; 

Và sau đó trong phần mở rộng của lớp, chỉ cần khai báo biến __strong.

@interface TheClassName() 
{ 
    __strong NSDate* _theDate; 
} 
@end 

Và tổng hợp chúng một cách thích hợp trong việc thực hiện

@implementation TheClassName 
@synthesize theDate = _theDate; 

Bây giờ bạn có thể thiết lập các biến ví dụ.

_theDate = [NSDate date]; 

Và ARC sẽ nhập nội dung thích hợp vào mã của bạn để coi đó là biến mạnh/giữ lại. Điều này có lợi thế là nhanh hơn các thuộc tính kiểu cũ (giữ lại) cũng như ARC inline mã lưu giữ/giải phóng lúc biên dịch.

+0

Bạn cũng có thể để _ tắt tên iVar trong trường hợp này vì self.theDate sẽ tăng cảnh báo vì không có getter được tổng hợp và __strong ngăn bạn không phải lo lắng về việc cài đặt iVar một cách không đúng cách do nhầm lẫn. – Shinohara

+0

nhưng những gì, nếu tôi muốn setter hoặc getter thực hiện các nhiệm vụ bổ sung, tức là thông báo phát sóng, kiểm tra sanity? – vikingosegundo

+0

Sau đó, bạn khai báo thuộc tính và viết bất kỳ phương thức getter hoặc setter nào mà bạn cần, khai báo __strong sẽ ngăn cản bạn phải thực hiện bất kỳ logic giữ lại/giải phóng nào trong setter. – Shinohara

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