2010-07-26 24 views
19

Sau đây không khiếu nại khi biên dịch cũng như thời gian chạy về không có name ivar. Vì vậy, tại sao nó lại phổ biến để thấy một ivar @property/@synthesize.Mục đích của ivar khi tài sản tồn tại là gì?

@interface PropTest : NSObject 
{ 
} 
@property (retain) NSString *name; 
@end 

@implementation PropTest 
@synthesize name; 
@end 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    PropTest *p = [[PropTest new] autorelease]; 
    p.name = @"Hello, World!"; 
    NSLog(@"%@",p.name); 
    [pool drain]; 
    return 0; 
} 

Mã này in

Hello, World! 

Trong thực tế, nếu tôi truy cập p->name, tôi nhận được một cảnh báo:

warning: instance variable 'name' is @private; this will be a hard error in the future 

mà chỉ ra rằng một Ivar được tạo ra cho tôi nếu một doesn' t tồn tại.

Nếu đó là sự thật, điểm tạo ra ngà bằng tay là gì (bỏ qua hiển nhiên, đôi khi có lý do hợp lệ để không sử dụng bộ truy cập g/setter)?

Hoặc được yêu cầu khác, tôi có nên chỉ bao giờ tạo một ivar cho thuộc tính khi tôi cần phải bỏ qua người truy cập không?

Trả lời

19

ivars tổng hợp (khả năng không khai báo bằng tay ivars) là một tính năng của thời gian chạy Objective-C mới, mà vẫn không được sử dụng trên tất cả các hệ thống. Đối với máy Mac 32 bit (và, cho đến gần đây, trình mô phỏng iPhone), bạn phải tự khai báo các dấu gạch ngang. Nếu bạn chỉ nhắm mục tiêu các hệ thống có thời gian chạy mới, không có lý do gì để khai báo ivars theo cách thủ công.

+0

Tôi nghĩ như Cris cho biết có một số vấn đề không khai báo ivars. Gỡ lỗi là một trong những mà tôi chạy vào khá thường xuyên. – Ian1971

8

Câu trả lời của eman là chính xác tổng thể, nhưng có một lý do để vẫn khai báo ivars ngay cả trong thời gian chạy mới: Apple không khuyến khích các trình tổng hợp trong các phương thức init và dealloc. Về cơ bản, getters và setters được phép có các tác dụng phụ ngoài việc thiết lập một biến. Đặc biệt, họ có thể kích hoạt thông báo KVO. Với một ngà voi để nói chuyện, bạn chỉ có thể gửi release và được thực hiện với nó. Nhưng nếu tất cả những gì bạn có là tài sản, lựa chọn duy nhất của bạn là đặt nó và hy vọng bạn tránh được bất kỳ tương tác không may nào.

Tôi không chắc vấn đề này thực tế lớn như thế nào, phải trung thực. Tôi chỉ mê tín dị đoan tránh nó, mặc dù tôi bí mật nghi ngờ nó sẽ gây ra một vấn đề trong hầu hết các trường hợp. Nhưng Apple làm cho một điểm này trong tài liệu, vì vậy tôi giả sử có một số lý do để được quan tâm.

lý do
+1

Bạn vẫn có thể truy cập trực tiếp ivar bằng các thanh tổng hợp (có lỗi mà bạn không thể nhưng tôi chắc chắn nó đã được sửa), vì vậy đây không phải là vấn đề. – shosti

+0

@eman: IIRC họ đang lên kế hoạch sửa lỗi, nhưng nó không có trong trừ khi bạn đang sử dụng các bản dựng Xcode tiền phát hành. – Chuck

+6

Truy cập trực tiếp các tổng hợp ivars hoạt động theo 3.2.4. –

7

Hai không-để-tốt-nhưng-cần thiết để đảm bảo tính chất này được hỗ trợ bởi ivars:

  1. Đối với một số lý do debugger XCode không hiển thị các thuộc tính mà không có ivars tương ứng một cách rõ ràng khai báo.
  2. Dường như với tôi rằng trong một số trường hợp sử dụng mà không có một @property Ivar có thể ẩn ivars khác, kết quả là lỗi biên dịch (xem Why does a subclass @property with no corresponding ivar hide superclass ivars?)

Trừ khi tôi đã có kết thúc sai trái của một vài gậy đây , Tôi nghĩ rằng việc sử dụng @property mà không có ivars rõ ràng có thể dẫn đến những phiền toái không được bảo đảm bởi sự tiện lợi.

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