2011-12-12 42 views
8

Tôi có thuộc tính BOOL mà tôi muốn đặt trong trình khởi tạo lớp của mình.Cách đúng để thiết lập thuộc tính BOOL

@property (assign, nonatomic) BOOL isEditMode; 

- (id)init 
{ 
    . . . 
    [self setValue:NO forKey:isEditMode]; 
    return self; 
} 

Trình biên dịch cung cấp cho tôi cảnh báo "Số nguyên không tương thích với chuyển đổi con trỏ". Tôi làm gì sai ở đây?

Trả lời

16

Phương thức mã hóa khóa-giá trị setValue:forKey: chỉ chấp nhận đối tượng làm đối số. Để thiết lập BOOL, bạn cần phải bọc số trong một đối tượng giá trị với [NSNumber numberWithBool:NO]. Nhưng có rất ít lý do để làm điều đó. Mã hóa khóa-giá trị là một cách vòng xoay để thực hiện việc này. Hoặc là self.isEditMode = NO hoặc chỉ isEditMode = NO. Phương thức thứ hai thích hợp hơn trong phương thức init (bởi vì các setters có thể chạy mã tùy ý mà có thể không được mong muốn trước khi một đối tượng được thiết lập đầy đủ).

Nhưng để xây dựng điểm đầu tiên: Lý do Khóa-giá trị mã hóa hoạt động theo cách này là do hệ thống kiểu không thể đại diện cho đối số đôi khi là đối tượng và vào thời điểm khác giá trị nguyên thủy. Vì vậy, KVC luôn giao dịch với các đối tượng và chỉ tự động hóa các giá trị nguyên thủy khi cần thiết. Tương tự, nếu bạn làm [yourObject valueForKey:@"isEditMode"], bạn sẽ lấy lại một đối tượng NSNumber gói giá trị thực.

2

Bạn chỉ có thể gán giá trị trực tiếp:

isEditMode = NO; 
+2

'setValue: forKey:' là phương thức của NSObject. Nó sẽ có hiệu lực đối với bất kỳ đối tượng Cocoa nào. – Chuck

+0

vấn đề với việc sử dụng KVC khi đặt giá trị BOOL là gì? KVC chỉ dành cho các đối tượng? – NSExplorer

+3

Nếu bạn đang sử dụng KVC để đặt, khóa là một chuỗi. 'isEditMode' là boolean ivar thực trong lớp của bạn; những gì bạn muốn là '@" isEditMode "', một chuỗi đặt tên là ivar. –

2

Tôi nghĩ bạn có nghĩa là:

self.isEditMode = NO; 

Nếu mã của bạn không thực sự biên dịch (Tôi khá mới để Objective-C vì vậy tôi không biết) setValue có thể mất một con trỏ đến một chuỗi (@"isEditMode", ví dụ) và không phải một số loại khác (isEditMode, ví dụ).

+0

Một setter sẽ hoạt động, nhưng không cần thiết. OP cho biết anh ta muốn đặt giá trị trong class initializer và anh ta đã không định nghĩa lại setter trong tuyên bố tài sản của mình. – Jim

5

Cú pháp đúng để thiết lập một tài sản chỉ

self.isEditMode = NO; 

là Nếu bạn muốn sử dụng -setValue:forKey: bạn phải viết nó như

[self setValue:[NSNumber numberWithBOOL:NO] forKey:@"isEditMode"]; 

Tuy nhiên, có hoàn toàn không có lý do để làm điều này trong tình huống của bạn.

Điều đó nói rằng, kể từ khi bạn đang ở trong một phương pháp init, tôi sẽ khuyên tránh bất kỳ truy cập tài sản nào và thay vào đó sử dụng Ivar trực tiếp, như trong

isEditMode = NO; 

Điều này tránh khả năng xảy ra một setter ghi đè là được gọi (hoặc trong lớp này hoặc một lớp con) mà làm cho giả định rằng đối tượng đã hoàn thành khởi tạo. Vì lý do này, bạn cũng muốn tránh quyền truy cập thuộc tính bên trong số -dealloc.

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