使用属性或直接访问ivars的特定性能和行为差异。
对于全局变量,使用它有什么区别:
@interface myClass (){
UIImageView *myView;
}
-(void)loadView{
[super loadView];
myView = [[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)];
}
这样做:
@interface myClass (){
}
@property (nonatomic, strong) UIImageView *myView;
@synthesize myView = _myView;
-(void)loadView{
[super loadView];
myView = [[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)];
}
每种方法都有什么好处? 建议总是使用属性的原因是什么?
答案 0 :(得分:4)
在第一种情况下,您的实例变量(或ivar)myView
对于该类是私有的,并且不能被另一个类访问。
在第二种情况下,您提供了一个属性,允许其他类通过合成访问器访问您的ivar。声明属性的替代方法是编写自己的访问器方法。 @synthesize
符号可以帮助您。
答案 1 :(得分:4)
始终为每个数据成员创建
@property
,并使用self.name
在整个类实现中访问它。 从不直接访问您自己的数据成员。
- 属性强制执行访问限制(例如readonly)
- 属性强制执行内存管理策略(保留,分配)
- 属性(很少)用作线程安全策略(原子)的一部分
- 属性提供了透明地实现自定义setter和getter的机会。
- 使用单一方法访问实例变量可提高代码可读性。
您还可以查看:The Code Commandments: Best Practices for Objective-C Coding
答案 2 :(得分:3)
Synthesize使您获得自动调用的getter和setter方法,具体取决于您是尝试读取还是写入值。对于myView属性:
myView = newView1; // using direct ivar access
myobject.myView = newvew1; // eq [myobject setMyView:newvew1]; where setMyView: is generated for you automatically with respect to assign/retain, the same for reading:
newvew1 = myobject.myView; // newvew1 = [myobject myView:newvew1];
生成的getter / setter名称可以使用setter = / getter =自定义,如果你不需要setter使用readonly。
你无法禁止其他类使用合成的getter和setter,默认情况下,ivars是@protected,如果你想让其他类访问ivars,你可以在@public下声明它们:
@interface myClass (){
UIImageView *myView; // this is protected
@public
UIImageView *myPublicView; // this is public
}
答案 3 :(得分:1)
在您的第一个示例中,您可以直接访问您的ivar并更改其内容。在您的第二个示例(属性)中,已自动创建一个ivar来支持该属性,并且您设置和获取属性的所有调用都将作为消息发送(例如:[self setMyView:[[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)]];
)。存取方法也是自动创建的。这意味着您现在正在遵循KVC / KVO协议。有关此设计的好处的更多信息see here