iOS中property用法梳理

2017-07-25  本文已影响40人  九九丸子

为什么要用property属性,理解"属性"的概念.

"属性"(property)是Objective-C的一项特性,用于封装对象中的数据.Objective-C对象通常会把其所需要的数据保存为各种实例变量.实例变量一般通过"存取方法"来访问.getter用于读取变量,setter用于写入变量.

如果用如下方式,声明实例变量,这是Java或C++常用的写法,在这些语言中可以定义实例变量的作用域.

@interface VVPerson : NSObject
@public
    NSString *_nickName;
    NSString *_age;
@private
    NSString *_otherData;
@end

但是上面这种做法在OC却存在问题:对象布局在编译期就已经固定了,只要碰到访问_nickName变量的代码,编译器会替换为"偏移量"(offset),这个偏移量表示:该变量距离存放对象的内存区域的起始地址有多远.但是如果增加一个实例变量,比如:

@interface VVPerson : NSObject

@public
    NSDate *_birthDay;
    NSString *_nickName;
    NSString *_age;
@private
    NSString *_otherData;
@end

原来表示 _nickName的偏移量现在指向了 _birthDay.OC对这种问题的解决办法是,把实例变量当做一种存储偏移量所用的"特殊变量",交由"类对象"保管.偏移量会在运行期查找,如果类的定义变了,那么存储的偏移量也就变了,这样无论何时访问实例变量,总能找到正确的偏移量.这就是稳固的"应用程序二进制接口"(Application Binary Interface ,ABI).ABI定义了生成代码时所遵守的规范.有了这种ABI,就可以在实现文件中定义实例变量了.以便保护与类实现有关的内部信息.

这种问题还有一种解决办法,就是不直接访问实例变量,通过个getter和setter.OC语言存取方法有着严格命名规范,所以能根据名称自动创建存取方法.@property语法就是一种标准的写法:编译器会自动写出一套存取方法,用以访问给定类型中具有给定名称的变量.

如果使用了属性,编译器会自动访问属性的方法,此过程叫做"自动合成"(autosynthesis).这个过程由编译器在编译期执行.编译器自动在属性名前加下划线,作为向类中添加的实例变量.

@implementation VVPerson

@synthesize nickName = _nickName;
@synthesize age = _age;
@end
@implementation VVPerson

@ dynamic nickName = nickName , age;

@end

属性的四类特质

原子性

atomic(原子性)和nonatomic(非原子性).如果属性具备atomic(原子性),则使用同步锁. nonatomic(非原子性)则相反.iOS开发中都用nonatomic的原因是:在IOS中使用同步锁的开销较大,这会带来性能问题.属性是原子的也并不能保证线程安全,想保证线程安全还需使用更深层的锁定机制.

读写权限

内存管理语义


未完待续

上一篇下一篇

猜你喜欢

热点阅读