OC属性与实例变量
OC属性与实例变量
无论是java还是c++这些面向对象的语言都会有属性这一概念,通常而言,对于java属性和实例变量没有什么区别,java官方定义的属性如下:
属性是指get或者set方法名 去掉get或者set后,把剩余的部分首字母改为小写后,即为这个类的属性
其实objective-C与之类似,但是在一般的开发中,oc类的实例变量都不会被直接读写,而是通过getter和setter方法来进行读写操作。原因如下:
直接读写实例变量实质上是在编译的过程中,对.h文件中声明的各个实例变量的偏移量进行操作。众所周知,OC属于运行时的动态语言。如果在运行时再添加实例变量,则原来的实际偏移量就会出现错误,内存布局的改变会导致直接读写实例变量出现错误。
但是如果将实例变量的读写修改为通过getter和setter方式的通知(OC的方法可看作为消息传递),而这些对象方法则存于类对象中,这样就可以解决上述问题。
OC将实例变量当作一种存储偏移量所用的"特殊变量",并将其交给类对象来进行保管,这样做的好处就是系统会在运行期进行查找,若类的定义在运行期改变了,那么存储的偏移量也就随之改变。
通过setter方法来修改类的实例变量,还可以触发属性的KVO。如果是直接改变实例变量,则无法触发。
属性的自动合成
使用 @property+类型名+属性名 可以让编译器自动编写这些属性需要的方法。
例如:
@property NSString *autoCreatedStr
在添加了property关键字后,编译器会自动合成以下的setter和getter方法:
- (void) setAutoCreatedStr:(NSString *)autoCreatedStr;- (NSString *) autoCreatedStr;
在自动合成属性前,编译器会自动为属性提供对应的实例变量,实例变量通常以下划线开头+属性名:
NSString *_autoCreatedStr;
@synthesize关键字
在iOS6之前,编译器是不会在设置完@Property后自动生成实例变量的,当设置完属性后还要额外再加上一句:
@synthesize autoCreatedStr = _autocreatedStr;
加上这句以后,才能完成添加名为"_autoCreatedStr"的实例变量。
但是在iOS6以后,LLVM编译器就会为每个属性添加上对应的@synthesize关键字,并且默认实例名为:下划线开头+属性名的格式。
所以在一般的开发中,只有想要自定义实例变量名的时候,才会在.m文件中手动添加@synthesize来覆盖原来的自动合成的以下划线开头的变量名。(一般来说都无需修改默认的实例变量名)
@dynamic关键字
dynamic关键字主要是用来通知编译器无需因为@property关键字而自动合成属性(包括生成实例变量和合成getter、setter方法)。
在编译的过程中,编译器不会因为没有定义读写方法而报错,因为@dynamic关键字默认了读写方法会在运行时生成。例如在分类中利用关联对象来给分类添加属性等。
总结
- OC开发中,通常不会直接对实例变量操作,而是通过getter和setter方法来对实例变量来进行读写。
- ios6后property关键字会自动合成实例变量和读写方法。
- dynamic关键字大部分情况其实用不到。
没有评论:
发表评论