2012-05-02 23 views
9

Tôi vừa mới cập nhật để Xcode 4.3.2 và thấy rằng bây giờ tôi có thể khai báo các biến Ví dụ tin bên @implementation khối như sau:Đây có phải là một cách mới để định nghĩa các biến cá thể riêng trong Objective-C không?

@interface TestClass : NSObject 
@property (nonatomic, copy) NSString *testProp; 
@end 

@implementation TestClass { 
    NSString *_testPropStore; 
} 

- (NSString *)testProp { return _testPropStore; } 
- (void)setTestProp:(NSString *)testProp { _testPropStore = [testProp copy]; } 

- (id)init { 
    if (self = [super init]) { 
     _testPropStore = nil; 
    } 
    return self; 
} 

@end 

Thông báo các NSString *_testPropStore dòng bên @implementation khối cú đúp.

Tôi cũng đã thử nghiệm với đoạn mã sau:

TestClass *c1 = [[TestClass alloc] init]; 
TestClass *c2 = [[TestClass alloc] init]; 

c1.testProp = @"Hello"; 
c2.testProp = @"World"; 

NSAssert(c1.testProp == c2.testProp, @"It's working!"); 

Mà dường như làm việc tốt. (Đó là, ứng dụng gặp sự cố với thông báo "Đang hoạt động" ở dòng NSAssert.)

Vì vậy, đây là tính năng mới của Objective-C để khai báo biến cá thể không? Kể từ khi tôi phát hiện ra điều này một cách tình cờ, tôi rất muốn biết nếu nó chỉ là để tuyên bố biến cá thể tư nhân hoặc sẽ có bất kỳ tác dụng phụ mà tôi không biết?

Tôi không thể tìm thấy bất kỳ tài liệu nào có liên quan vì hầu hết các câu hỏi thuộc loại này với từ private vừa kết thúc với câu trả lời về cách khai báo chúng trên danh mục mở rộng riêng.

Trả lời

19

Đó là thực tế, đó là cách mới, * tuyệt vời và, vâng, nó nằm trong tài liệu. The Objective-C Programming Language, gần với chúng tôi để có thông số thực tế cho ngôn ngữ, có các thông tin sau để nói:

Định nghĩa của một lớp được cấu trúc rất giống với tuyên bố của nó. Nó bắt đầu với chỉ thị @implementation và kết thúc bằng chỉ thị @end. Bên cạnh đó, lớp có thể khai báo các biến Ví dụ trong dấu ngoặc sau khi chỉ thị @implementation:

@implementation ClassName 
{ 
    // Instance variable declarations. 
} 
// Method definitions. 
@end 

Ngoài ra còn có một lưu ý lịch sử một cách ít lại từ liên kết đó, việc giải quyết một thực tế mà chúng ta đã từng có tuyên bố ivars trong khối giao diện:

Trước đây, giao diện yêu cầu khai báo biến thể của lớp, cấu trúc dữ liệu là một phần của mỗi thể hiện của lớp. ... Các biến thể hiện đại diện cho một chi tiết thực hiện, và thường không nên được truy cập bên ngoài chính lớp đó. Hơn nữa, bạn có thể khai báo chúng trong khối thực hiện hoặc tổng hợp chúng bằng cách sử dụng các thuộc tính đã khai báo. Thông thường, bạn không nên, do đó, khai báo các biến mẫu trong giao diện công cộng và vì vậy bạn nên bỏ qua các dấu ngoặc.

Đối với câu hỏi về quyền riêng tư, có, các biến này thực sự riêng tư - chúng hoạt động như các thanh ngang được khai báo trong giao diện với chỉ thị @private. Điều này có nghĩa là các lớp con không thể truy cập chúng theo mặc định.tầm nhìn của họ có thể được thay đổi, tuy nhiên, sử dụng một trong hai @protected hoặc (nếu cần thiết đối với một số lý do kỳ lạ) @public:

@interface Stuper : NSObject 
@end 

@implementation Stuper 
{ 
    @protected 
    NSString * sangfroid; 
} 
@end 

@interface Stub : Stuper 
- (void)setSangfroid: (NSString *)newSangfroid; 
@end 

@implementation Stub 

- (void)setSangfroid: (NSString *)newSangfroid { 
    sangfroid = [newSangfroid copy]; 
} 

* Bạn phải sử dụng kêu vang> 3.0, tôi tin rằng, do đó chỉ là một vài tháng trước đây là của bài đăng này. GCC sẽ không làm điều đó.

+0

Tôi tò mò hơn về cách thực hiện điều này dưới mui xe. Thời gian chạy Objective-C biết bao nhiêu bộ nhớ để cấp phát cho lớp nếu tiêu đề có định nghĩa không đầy đủ? – mpontillo

+0

Đó sẽ là một câu hỏi tuyệt vời để đăng. Nó gần như chắc chắn có một cái gì đó để làm với ["không mong manh ivars"] (http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html). –

+0

FYI, liên kết trong câu trả lời của bạn dường như bị hỏng đối với tôi. –

2

Nó khá mới và nó hợp lệ miễn là bất kỳ trình biên dịch nào bạn cần hỗ trợ.

Thật tuyệt vời để giảm thiểu sự phụ thuộc của bạn - bao gồm và chuyển tiếp có thể nằm trong tệp triển khai. Vì lý do này, và nếu tất cả các trình biên dịch bạn sử dụng hỗ trợ nó, thì đó là một nơi tốt hơn cho ivars của bạn hơn trong khối @interface.

Thông báo cuối cùng là các trình gỡ rối hiện tại (có thể.2.2012) của chúng tôi không hỗ trợ điều này.

+2

Điểm rất tốt về trình gỡ rối. Có một chuỗi nhỏ về điều này trong danh sách lldb.devel: http://comments.gmane.org/gmane.comp.debugging.lldb.devel/624 –

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