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