属性与实例变量

use*_*292 44 objective-c

可能重复:
objective-c/cocoa/cocoa-touch中的"实例变量"和"属性"之间是否存在差异?

在Objective C中你想要使用实例变量vs属性的情况是什么?有人可以提供真实的例子吗?

Fei*_*anZ 88

实例变量对于类是唯一的.默认情况下,只有类和子类可以访问它.因此,作为面向对象编程的基本原理,实例变量(ivars)是私有的 - 它们由类封装.

相反,属性是可以与实例变量对应或不对应的公共值.如果你想公开一个ivar,你可能会做一个相应的财产.但与此同时,您希望保密的实例变量没有相应的属性,因此无法从类外部访问它们.您还可以拥有与ivar不对应的计算属性.

没有财产,ivars可以隐藏.实际上,除非在公共标题中声明ivar,否则很难确定存在这样的ivar.

一个简单的比喻就是收缩包装的书.财产可能是title,author或精装与软包."ivars"将是本书的实际内容.在拥有本书之前,您无权访问实际文本; 除非您拥有该课程,否则您无法访问ivars.


更有趣的是,属性更好地集成到运行时中.现代64位运行时将为访问器属性生成一个ivar,因此您甚至不需要创建ivar.属性实际上是方法:

// This is not syntactically correct but gets the meaning across
(self.variable) == ([self variable];)
(self.variable = 5;) == ([self setVariable:5];)
Run Code Online (Sandbox Code Playgroud)

对于每个属性,有两种方法(除非声明属性readonly,在这种情况下只有一个):有getter,它返回与ivar相同的类型,并且与ivar同名,以及该设定器(其不与声明readonly的ivar); 它返回void,其名称只是设置在变量名前面.

因为它们是方法,所以您可以对它们进行动态调用.使用NSSelectorFromString()和各种performSelector:方法,您可以制作一个有很多可能性的非常动态的程序.

最后,属性在Core Data和Key-Value Coding中得到广泛使用.Core Data是一个高级框架,用于在SQLite数据库中存储数据,同时提供清晰的Obj-C前端; KVC在整个Core Data中使用,是一种访问属性的动态方式.它在编码/解码对象时使用,例如从XIB读取时.

  • 您可以在类扩展中声明属性以使它们"保密",同时有利于它们提供的内存管理封装和样板代码消除. (10认同)
  • 是.自从我写这个答案后,属性/ ivars发生了一些变化......现在所有属性都带有隐式的ivars(`@property var`也使得ivar`_var`可用).在`.m`中声明的属性现在是创建私有字段的"最佳"方式 (4认同)
  • @VanDuTran:属性实际上与内存管理无关.在访问值(以及控制访问权限)方面,它们是1/3语义,2/3功能.他们也有优势运行时,就像我在下半年描述我的帖子,你不能做到这一点与实例变量,因为'的方法@ property`结果和运行时系统的工作原理与方法. (2认同)