内容简介:补充atomic是自旋锁,即当上一线程没有执行完毕(被锁住),下一线程会一直等待(不会进入睡眠状态),当上一线程执行完毕,下一线程立即执行。他区别于互斥锁,互斥锁在等待的时候,会进入睡眠状态,当上一个线程执行完毕,睡眠状态就会被唤醒,然后再执行。
property
属性关键字我们在日常的开发中经常会用到,所以我们有必要对其有充分的了解,这样对于我们日常开发使用时就能做到知其所以然。
####property关键字介绍 property
关键字分为四类:
-
原子性:
atomic
和nonatomic
,property
中默认是atomic
,也就是线程安全,但是我们一般使用的是nonatomic
。因为atomic
的线程安全系统资源开销相对较大,影响性能,即使我们需要使用线程安全,我们也可以使用其他方法实现。atomic实现原理是在getter
、setter
中使用@synchronized
同步锁关键字进行代码块锁定而实现的。
补充atomic是自旋锁,即当上一线程没有执行完毕(被锁住),下一线程会一直等待(不会进入睡眠状态),当上一线程执行完毕,下一线程立即执行。他区别于互斥锁,互斥锁在等待的时候,会进入睡眠状态,当上一个线程执行完毕,睡眠状态就会被唤醒,然后再执行。
-
引用计数相关:
assign
、retain
、weak
、strong
、copy
、iOS5以前使用的unsafe_unretained
。 assign :主要修饰基本数据类型,不能修饰对象类型,如NSInterger
,CGFloat
等类型。并且统一由系统栈进行内存管理。 retain :修饰对象类型,强引用对象,并是对象引用计数加1,可用于MRC
环境中。 weak :修饰对象类型,对对象弱引用,不增加对象的引用计数。如果对象销毁了,指针会自动指向nil
,所以可以防止野指针的问题。 strong :修饰对象类型,对对象强引用,会增加对象的引用计数。如果指向了空对象,会造成野指针。只能用于ARC
环境。 copy :在一个新对象引用计数为1,赋值时对传入值进行一份拷贝,所以才使用copy关键字。你将一个对象赋值给一个属性,该属性并不会持有对象,而是会创建一个新对象,并将这个对象拷贝给它。使用copy
关键字的对象必须实现NSCoding
协议。 unsafe_unretained :跟weak
类似,声明一个弱引用,区别是当引用计数为0时,变量不会自动设置为nil
。 -
读写权限相关:默认是
readwrite
(可读可写),还有readonly,修饰属性时,属性不能被外界修改。 -
方法名:可设置属性的
setter
和getter
方法名。 ####补充介绍weak
关键字 :
- 使用场景 用于一些对象互相引用时,避免出现互相强引用而导致的循环引用,对象不能释放的。
-
实现原理
weak
修饰时,runtime
会维护一个hash
表(也称为weak
表),用于存储对象的所有weak
指针,hash
表的key
是该对象的地址,value
为weak
指针的地址(这个地址的值是所指对象的地址)数组。(备注strong
是通过runtime
维护的一个自动引用计数表)weak
的实现原理总结:
-
初始化时,
runtime
会调用objc_initWeak
函数,初始化一个新的weak
指针指向对象地址; -
添加引用时,
objc_initWeak
函数会调用objc_storeWeak
函数,objc_storeWeak
的作用是更新指针指向,创建对应的弱引用表(hash表); -
释放时,调用
clearDeallocating
函数。clearDeallocating
函数首先根据对象地址获取weak
指针地址的数组,然后遍历这个数组把其中指向空对象的指针设为nil
,最后把这个指针从weak
表中删除,最后清理对象的记录。
copy
和 strong
:
讲这两个字之前我们需要了解深复制和浅复制相关的只是,可以参考这里。具体示例如下:
@property (nonatomic, copy) NSMutableArray *mutArray; NSMutableArray *mutArray1 = [NSMutableArray array]; self.mutArray = mutArray1; 复制代码
等同于
@property (nonatomic, strong) NSMutableArray *mutArray; NSMutableArray *mutArray1 = [NSMutableArray array]; self.mutArray = [mutArray1 copy]; 复制代码
经过测试之后我们知道使用copy修饰的 mutArray
数组,当调用它的 setter
方法,它会建立一个引用计数为1的新对象,然后释放旧对象。而 copy
修饰的属性赋值时经过 copy
其实已经变成了不可变数组。而使用可变数组的增、删、改、查函数是会发现找不到相关的实例方法而 crash
。
NSString 为什么用 copy 而不用 retain我们通过实例来看看:
@property (nonatomic, retain) NSString *string; NSMutableString *string1 = [[NSMutableString alloc] initWithString:@"abc"]; self.string = string1; [string1 appendString:@"123"]; NSLog(@"============== %@ =========", self.string); 2019-06-19 17:08:58.114333+0800 ThinTableVIew1[96955:2656816] ============== abc123 ========= 复制代码
从打印的信息可以看到当改变 string1
的值时, self.string
的值也改变了。下面我们通过查看 string
属性 setter
方法的实现来探究一下原理:
@property (nonatomic, retain) NSString *string; - (void)setString:(NSString *)string { if (_string != string) { [_string release]; _string = [string retain]; //相当于 //[string retain]; //_string = string; } } ================== @property (nonatomic, copy) NSString *string; - (void)setString:(NSString *)string { if (_string != string) { [_string release]; _string = [string copy]; } } 复制代码
我们可以知道:
-
当使用
retain
修饰string
时调用的是_string = [string retain]
,这样只会增加string的引用,而_string
指针和string
是指向同一块内容。所以改变string
的内容同样的会改变_string
的内容。 -
当使用
copy
修饰string
时,当传入的对象是可变对象时,调用的是[string copy]
;会创建一个新的对象赋值给_string
,所以_string
和string
不会互相干扰,而改变string
的内容不会影响_string
。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- synchronized关键字使用详解
- swift中的声明关键字详解
- 番外篇2-基本规范、注释、static关键字、import关键字
- 说说iOS中的常用的关键字static ,class(仅限Swift关键字)
- Golang 关键字
- 2019 关键字
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First JavaScript程序设计
[美]Eric T. Freeman、[美] Elisabeth Robson / 袁国忠 / 人民邮电出版社 / 2017-9 / 129.00 元
本书语言和版式活泼,内容讲解深入浅出,是难得的JavaScript入门书。本书内容涵盖JavaScript的基本知识以及对象、函数和浏览器文档对象模型等高阶主题。书中配备了大量有趣的实例、图示和练习,让读者轻轻松松掌握JavaScript。一起来看看 《Head First JavaScript程序设计》 这本书的介绍吧!