is the solution as simple as: only with a property can an ivar be set from 'outside'?
本質上說,是的。 Obj-C中的Ivars(默認情況下)是「protected」,這意味着編譯器不允許你在對象自己的代碼外部訪問它們。例如,給定下面的類聲明:
@interface Dunstable : NSObject
{
NSString * crunk;
}
@end
你可能會覺得你能夠創建對象後訪問伊娃,而是試圖將導致一個錯誤:
Dunstable * d = [[Dunstable alloc] init];
d->crunk = @"Forsooth"; // Error: "Instance variable 'crunk' is protected
這就是爲什麼ObjC使用訪問器方法。手動定義它們是強制性的聲明的屬性來臨之前:
@implementation Dunstable
- (NSString *)crunk {
return crunk; // implicit ivar access, i.e. self->crunk
}
- (void)setCrunk: (NSString *)newCrunk {
[newCrunk retain];
[crunk release];
crunk = newCrunk;
}
@end
現在,使用@property
和@synthesize
指令創建你的訪問方法(以及變量本身)。 (在二傳手的手動內存管理,當然也根據ARC已經過時了。)
這是可能使伊娃這是從對象外部訪問:
@interface Dunstable : NSObject
{
@public
NSNumber * nonce;
}
@end
Dunstable * d = [[Dunstable alloc] init];
d->nonce = [NSNumber numberWithInt:2]; // Works fine
但這不考慮良好的Objective-C風格。
The Objective-C Programming Language文檔包含一個「歷史說明」這一點:
Note: Historically, the interface required declarations of a class’s instance variables, the data structures that are part of each instance of the class. These were declared in braces after the @interface
declaration and before method declarations: [...] Instance variables represent an implementation detail, and should typically not be accessed outside of the class itself. Moreover, you can declare them in the implementation block or synthesize them using declared properties. Typically you should not, therefore, declare instance variables in the public interface and so you should omit the braces.
這是一個相當大的改變(實際上,我是驚訝,有沒有在該文檔中@interface
宣佈了高德給出的語法),但它絕對是更好的。你應該使用聲明的屬性;他們做正確的事情,並使您的代碼更清潔和更安全。
這真是一個很好的答案!現在我想知道ARC的到來,使用propet而不是必須保留和發佈ivars,看看'[newCrunk retain]; [crunk release];'在你的示例中? – 2012-03-24 19:28:32
是的,現在這種方法是完全不必要的(並且用ARC,非法寫入)。這只是過去的一個例子。 – 2012-03-24 19:29:43
allright =)我已經掌握了它,現在感謝你在這裏的所有答案。感謝iulius提供最清晰,最完整的作品,並花時間去搜索歷史筆記。其非常讚賞=) – 2012-03-24 19:38:15