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