如果在 .h 文件中声明了一个对象 (ivar),那么它是公共的,这是不正确的。只有提供了 getter/setter 方法,否则不提供。
确实,@property/@synthesize 指令是用于声明和定义默认 getter/setter 方法的工具。因此,您只需使用指令,而不是自己编写它们。
还值得注意的是,声明属性可以使用点符号来引用对象的属性。而且他们澄清了很多,感谢retain/assign/copy 说明符,如何为这些属性管理内存。 (当然,@synthesize 会为您正确地做到这一点。
实际上,关于您的样本,ivar 是否与属性相关联是一种设计选择。可能,您只需重新考虑默认情况下在 .h 文件中声明的 ivars 是公共的假设,它会变得更加清晰。换句话说:primaryKey 是公开的,database 不是。
一个很好的教程可以找到here,但也不要忘记Apple docs。
编辑:
关于您在评论部分提出的问题:
不必每个 ivar 都有一个属性,也不必具有 getter/setter 才能在该类实现中使用。
@interface SomeClass : NSObject {
AnotherClass* _anotherClassObj;
AThirdClass* _aThirdClassObj;
}
@property (nonatomic, retain) AnotherClass* anotherClassObj;
@end
所以,这里有两个 ivars;只有一个有@property 声明。在您的 .m 文件中,您可能有,例如
@implementation SomeClass;
@synthesize anotherClassObj = _anotherClassObj;
- (void)initWithClasses:(AnotherClass*)obj1 and:(AThirdClass*)obj2 {
.....
self.anotherClassObj = obj1;
_aThirdClassObj = obj2;
...
}
....
@end
在这段代码中:
@synthesize 将为anotherClassObj 提供getter/setter 实现,因此您可以使用语法:self.anotherClassObj = obj1;该语法可以在类实现的内部和外部平等地使用;
当您没有 getter/setter(自动生成或自定义)时,您可以使用语法 _aThirdClassObj = obj2; 直接分配给 ivar,语义与简单指针复制;无论如何,_aThirdClassObj 将无法从该类外部访问;
-
此外,尽管有@property ... anotherClassObj,您仍然可以直接在您的.m 文件中引用_anotherClassObj,就像在_anotherClassObj = xxx 中一样,如果您需要的话,可以绕过getter/setter。
李>
您应该清楚的一点是,getter/setter 不仅是使 ivar“公开”的一种方式。它们在管理保留计数方面也发挥着重要作用(取决于您在属性声明中的保留/分配/复制中选择的说明符)。因此,在上面的self.anotherClassObj = obj1; 中,obj1 被分配给_anotherClassObj 并且它也被保留(如果_anotherClassObj 之前指向一个对象,那么该对象将被发送一个release)。原始 ivar 分配不提供那种设施。
在我看来,属性的保留计数管理功能在决定我是否使用属性方面远比可见性重要。