使用属性和不访问ivar之间的区别



使用属性或直接访问ivar的特定性能和行为差异。

对于全局变量,使用有什么区别

@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)];
    }

每种方法都能给我们带来什么好处?建议始终使用属性的原因是什么?

在第一种情况下,实例变量(或ivar)myView对类是私有的,其他类无法访问。

在第二种情况下,您提供了一个属性,允许其他类通过合成访问器访问您的ivar。声明属性的另一种选择是编写自己的访问器方法。@synthesize表示法可以为您做到这一点。

请参阅有关声明属性的Apple文档

ALWAYS为每个数据成员创建一个@property,并使用self.name在整个类实现中访问它。NEVER直接访问您自己的数据成员。

以下是使用Properties的一些原因:

  • 属性强制执行访问限制(例如只读)
  • 属性强制执行内存管理策略(保留、分配)
  • 属性(很少)被用作线程安全策略(原子)的一部分
  • 属性提供了透明地实现自定义setter和getter的机会
  • 使用单一方式访问实例变量可以提高代码的可读性

您还可以查看:代码命令:Objective-C编码的最佳实践

Synthesis使您可以获得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];

如果不需要setter使用readonly,则可以使用setter=/getter=自定义生成的getter/setter名称。

你不能禁止其他类使用合成的getter和setter,默认情况下ivar是@protective,如果你想为其他类提供对ivar的访问,你可以在@public:下声明它们

@interface myClass (){
   UIImageView *myView; // this is protected
   @public
   UIImageView *myPublicView; // this is public    
}

在第一个示例中,您可以直接访问ivar并更改其内容。在您的第二个示例(属性)中,已经自动创建了一个ivar来支持该属性,并且您对设置和获取该属性的所有调用都将作为消息发送(如:[self setMyView:[[UIImageView alloc] initWithFrame:CGrectMake(0,0,100,100)]];)。访问器方法也是自动创建的。这意味着您现在正在遵循KVC/KVO协议。有关此设计优点的更多信息,请参阅此处

最新更新