如下两个问题有没有哪位仁兄能给予证实。感激万分!
HaiTeng-Wang opened this issue · comments
-
大量博客中说assign是默认关键字。但没给相关文档链接。原谅我并未查找到相关文档中有说明“assign是默认关键字”。但是在官方的大量.h文件中。assign修饰值类型,确实是省略没有写。
-
原子性atomic作为iOS原子性语义,采用什么锁,来保证Setter/getter方法的完整性?
有的人说:“使用同步锁@synchronized”;还有的人说:“使用自旋锁”;还有的人说:“如果属性具备atomic特质,同步锁,nonatomic使用的是自旋锁。
1:oc对象默认是strong,因为你class_copyPropertyList后再property_getAttributes得到的是T@"NSString",&,V_name,其中&表示strong(c表示copy等),你可以谷歌一下;
普通对象是assign,这个获取不到,但是我们可以从runtime源码中找到相关的逻辑,你看看objc_AssociationPolicy枚举的定义以及内部处理的逻辑就知道了,还有一点就是你属性加不加assign用property_getAttributes得到的都是一样的值,可以返推回去结论成立。
2:非原子不会使用锁,则我们只考虑原子属性使用了什么锁。源码看不出来使用了什么锁,但是有另外的办法可以得到结果,有一个测试各种锁消耗时间的代码iOS中各种锁的耗时,你可以测试出来,以下是我用NSNumber类型的两个属性做的测试。
nonatomic: 227.57 ms
atomic: 299.54 ms
OSSpinLock: 83.32 ms
dispatch_semaphore: 138.98 ms
pthread_mutex: 239.70 ms
NSCondition: 235.18 ms
NSLock: 237.48 ms
pthread_mutex(recursive): 363.97 ms
NSRecursiveLock: 538.49 ms
NSConditionLock: 807.66 ms
@synchronized: 1062.45 ms
从这个表可以看出,只会是自旋锁OSSpinLock。
2:非原子不会使用锁,则我们只考虑原子属性使用了什么锁。源码看不出来使用了什么锁,但是有另外的办法可以得到结果,有一个测试各种锁消耗时间的代码iOS中各种锁的耗时,你可以测试出来,以下是我用NSNumber类型的两个属性做的测试。
nonatomic: 227.57 ms
atomic: 299.54 ms
OSSpinLock: 83.32 ms
dispatch_semaphore: 138.98 ms
pthread_mutex: 239.70 ms
NSCondition: 235.18 ms
NSLock: 237.48 ms
pthread_mutex(recursive): 363.97 ms
NSRecursiveLock: 538.49 ms
NSConditionLock: 807.66 ms
@synchronized: 1062.45 ms
从这个表可以看出,只会是自旋锁OSSpinLock。
objc源码里有objc_setProperty
// 省略上面一些无关的无关的代码 直接看核心
if (!atomic) {
oldValue = *slot;
*slot = newValue;
} else {
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
oldValue = *slot;
*slot = newValue;
slotlock.unlock();
}
在之前版本的源码里使用的是spinlock, 也就是mutex_tt,也就是os_unfair_lock
atomic 的底层实现,老版本是自旋锁,iOS10开始是互斥锁--spinlock底层实现改变了。
这篇文章说的很清楚: https://juejin.im/post/5e7ab7755188255e1a15baf9