- 开发者通过对象来 存储并传递数据。
- 在对象之间传递数据并执行任务的过程就叫做“消息传递”。
这两条特性的工作原理?
Objective-C运行期环境(Objective-C runtime) ,提供了使得对象之间能够传递消息的重要函数,并且包含创建类实例所用的全部逻辑。
第六条:理解“属性”这一概念
@interface EOCPerson : NSObject { @public //NSString *_dateOfBrith; NSString *_firstName; NSString *_lastName; @private NSString *_aomeInternalData; } @end
这种写法问题,对象布局在 编译器(compile time)就已经固定了。只要碰到访问——firstName变量的代码,编译器就把其替换为“偏移量”(offset),这个偏移量是“硬编码”(hardcode),表示带变量距离存放对象的内存区域的起始地址有多远。
但是又加了一个实例变量就会出错,原来表示_firstName的偏移量现在却指向 _dateOfBirth了。
Objective-C的应对做法是,把实例变量当作一种存储偏移量所用的“特殊变量”,交由“类对象(class object)保管。偏移量会在运行期查找,如果类的定义变了,那么存储的偏移量也就变了。这样甚至可以在运行期向类中新增实例变了,这就是稳固的”应用程序二进制接口“ABI。有了ABI,就可以在class-continuation分类或 实现文件中定义实例变量了
另一种解决办法:
1,通过@property语法来定义对象中所封装的数据
属性优势:如果使用了属性,编译器就会自动编写访问这些属性所的方法,此过程叫做”自动合成“(autosynthesis),此过程在编译器执行
@dynamic :告诉编译器:不要自动创建实现属性所用的实例变了,也不要为其创建存取方法。
属性特质 :
原子性
(atomicity) ,系统其他部分无法观察到其中间步骤所生成的临时结果,而只能看到操作前与操作后的结果,该操作就是(atomic)
读写权限
内存管理语义
(concrete ownership semantic) 具体的所有权语义
assign :”设置方法“只会执行针对”纯量类型“(scalar type, 例如CGFloat 或 NSInteger等)的简单赋值操作。
strong :表明该属性定义了一种”拥有关系“(owning relationship)为这种属性设置新值时,设置方法会先保留新值,并释放旧值,然后再将新值设置上去。
weak:表明该属性定义了一种”非拥有关系“(nonowning relationship)为这种属性设置新值时,设置方法会既不保留新值,也不释放旧值,与assign相似,再属性所致的对象遭到摧毁时,属性值也会清空(nil out)
unsafe_unretained : 此特质的语义和assign系那个痛,但它适用于”对象类型“(object type),该特质表达一种”非拥有关系"("不保留",unretained), 当目标对象遭到摧毁时,属性值不会自动清空(“不安全”,unsafe),这一点与weak有区别。
copy:与strong类似。但是设置方法并不保留新值,而是“拷贝”。当属性为NSString 时经常用来保护其封装性,因为有可能传递给设置方法的新值指向一个NSMutableString类的实例,可以修改其值的字符串,若不用copy那么设置完属性后,可能在对象不知情的情况下遭人更改
方法名:
getter=<name> 指定获取方法的方法名。如果属性是Boolean型,而你想加前缀“is",就可以用这个方法来指定。
如表示”开关“(switch)是否打开的属性就是 这样定义的:
@property (nonatomic, getter=isOn) BOOL on;
atomic 与 nonatomic 的区别是:
具备atomic特质的获取方法会通过锁定机制来确保其操作的原子性。也就是说如果两个线程读写同一属性,那么不论何时总能看到有效的属性值。若使用nonatomic 即不加锁,当一个线程正在改写某属性值时,另一个线程会突然闯入,把尚未修改好的属性值读取出来,读到的属性值可能不对。
使用同步锁的开销较大,性能不好。一般使用nonatomic属性。