内容简介:补充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 关键字
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Game Engine Architecture, Second Edition
Jason Gregory / A K Peters/CRC Press / 2014-8-15 / USD 69.95
A 2010 CHOICE outstanding academic title, this updated book covers the theory and practice of game engine software development. It explains practical concepts and techniques used by real game studios,......一起来看看 《Game Engine Architecture, Second Edition》 这本书的介绍吧!