2010-04-29 47 views
22

Tôi đã cố gắng tạo thuộc tính chỉ đọc. Tôi muốn khởi tạo với một giá trị từ lớp tạo ra một thể hiện của lớp này, ví dụ:Khởi tạo thuộc tính chỉ đọc

@property (retain,readonly) NSString *firstName;

Và tôi đã cố gắng để khởi tạo nó như thế này:

-(id)initWithName:(NSString *)n{ self.firstName = n; }

Một khi tôi đã làm điều này, trình biên dịch báo cáo một lỗi mà tài sản chỉ đọc không được chuyển nhượng. Vì vậy, làm thế nào tôi có thể làm điều này?

Trả lời

13

Không sử dụng setter tổng hợp:

firstName = [n retain]; //Or copy 

Nó thường được khuyên nên bỏ qua setters trong bất kỳ init và dealloc phương pháp anyway.

+0

Vấn đề với việc triển khai ở trên của tôi là giá trị không được giữ lại. Khi tôi thêm phần giữ lại vào thuộc tính, nhiệm vụ này sẽ đặt giá trị vào thuộc tính. Và nếu một số đối tượng khác truy cập thuộc tính này thì giá trị này sẽ ở đó. Tôi cũng đã sửa đổi câu hỏi của tôi – awsome

+0

Tại sao điều này lại là một vấn đề? Sử dụng 'firstname = [n retain]' sẽ chỉ đặt firstName thành con trỏ thành 'n'. Vì vậy, vâng, khi một số đối tượng khác truy cập thuộc tính này, giá trị sẽ ở đó. :) – Rengers

+0

Nếu tôi cố gắng làm theo cách này nếu tôi truy cập thuộc tính này, tôi nhận được ngoại lệ sau.Chương trình nhận được tín hiệu: “EXC_BAD_ACCESS”. Và lỗi này không phải do bất kỳ tài sản nào khác. Tôi đã điều tra điều này rất nhiều trong trình gỡ lỗi. Thuộc tính này hiển thị "ngoài phạm vi". Và nếu tôi chỉ định nó, self.firstName = n;. sau đó mọi thứ hoạt động tốt. – awsome

38

Hoặc gán trực tiếp biến mẫu (đừng quên thêm retain hoặc copy nếu bạn cần) hoặc redeclare thuộc tính trong tiện ích mở rộng lớp học riêng tư. Như thế này:

Trong file .h của bạn:

@property (readonly, copy) NSString *firstName; 

Trong file .m của bạn:

@interface MyClass() 

// Redeclare property as readwrite 
@property (readwrite, copy) NSString *firstName; 

@end 


@implementation MyClass 

@synthesize firstName; 
... 

Bây giờ bạn có thể sử dụng setter tổng hợp trong việc thực hiện của bạn, nhưng giao diện lớp vẫn cho thấy sự tài sản như chỉ đọc. Lưu ý rằng các lớp khác nhập tệp .h của bạn vẫn có thể gọi -[MyClass setFirstName:] nhưng chúng sẽ không biết rằng nó tồn tại và sẽ nhận được cảnh báo trình biên dịch.

+0

Điều này có vẻ là một giải pháp tốt. Cảm ơn. – awsome

+0

Có lợi thế nào khi sử dụng bộ tổng hợp so với cách tiếp cận được đề xuất bởi @Renger không? – Madbreaks

2

Bạn có thể trực tiếp truy cập vào bất động sản với:

_firstName = n;

Phương pháp setter mà self.firstName = n ngụ ý sẽ không được tổng hợp bởi vì bạn chỉ định readonly trong @property (retain,readonly) NSString *firstName;, vì thế mà lỗi biên dịch.

+0

không có _firstName ... –

+0

đó là sự hiểu biết của tôi rằng _firstName sẽ tồn tại. Nó là ngà cơ bản được tạo ra khi thuộc tính được khai báo. Kể từ Xcode 4.6 trình biên dịch sẽ tự động tạo ra điều này cho bạn. – Bob9630

+0

Đó cũng là sự hiểu biết của tôi quá @ Bob9630. Các câu trả lời khác cho câu hỏi này đã không tạo ra kết quả mong muốn trong trường hợp của tôi, trong khi điều này đã làm. –

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