Objetive-C 属性和线程安全
一、接上一篇《nonatomic 带来的线程安全问题》,这里继续详细讨论属性各种类型与线程安全的关系
1)影响线程安全的属性类型,nonatomic,atomic,weak
@property (atomic, strong) TestObject *obj;
@property (nonatomic, strong) TestObject *obj;
@property (atomic, weak) TestObject *obj;
@property (nonatomic, weak) TestObject *obj;
上面有4种属性的定义,在遇到下面的代码的时候
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
for (int i = 0; i < 10000; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// self.obj = [[TestObject alloc] init];
});
}
});
第1种定义不会crash,这是符合atomic的标准写法,通过setter、和getter访问器访问变量。
第2种定义会crash,因为nonatomic定义的属性,在setter中也没有加锁,所以多线程访问之下会出现问题。
第3种和第4种都不会crash,主要原因是,将对象赋值给weak指针的时候,都不会对对象的引用计数进行改变,
此外weak对象添加weak引用表标记的时候,还会对该对象进行加锁,因此杜绝了多线程问题。但是多线程访问之下,最好还是atomic。
2)如果一个对象是atomic,并且是通过下划线,实例变量访问的时候还是会crash。
因为所谓atomic是加在getter和setter中的,我们比较一下下面属性的定义翻译成汇编之后的不同
@interface ViewController () @property (atomic, strong) TestObject* x;
@property (nonatomic, strong) TestObject* y; @end
对应汇编:


注意最后调用的存储方法,一个是加锁版本,一个未加锁版本。在getter中,一个是通过方法返回的,一个是通过指针的偏移


二、总结
iOS中的属性和线程安全需要通过下面的方式保证:
1) 使用atomic定义属性,同时使用getter和setter能够保证这个对象本身的引用计数线程安全问题,也就是避免多线程导致的错误释放。
2) 使用weak定义属性,避免多线程中对引用计数的操作。
保证了属性的原子性性访问,并不代表业务上面的线程安全问题,业务上的线程安全问题。
业务的线程安全:
1)加锁,NSLock,递归所,自旋锁,读写锁,内存屏障
2)串行队列保证任务不会交替执行
3)使用单线程+异步的模型
Objetive-C 属性和线程安全的更多相关文章
- 线程的属性和 线程特定数据 Thread-specific Data
一.posix 线程属性 POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者可以访问和修改的线程属性.主要包括如下属性: 1. 作用域(scope) 2. 栈尺 ...
- C# 的界面控件属性修改线程安全问题
今天在实验delegate与thread 在初步的实验结束后,因为原来的delegate只有一个函数会被调用,感觉没有达到delegate的极致,所以又重新自己定义了一个delegate,在另一个线程 ...
- 线程属性总结 线程的api属性
http://blog.csdn.net/zsf8701/article/details/7842392 //线程属性结构如下:typedef struct{ int etachstate; //线程 ...
- 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程
进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...
- python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02
目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...
- pthread_attr_t 线程属性(二)
一.函数: 1.线程属性的初始化与销毁:#include <pthread.h>int pthread_attr_init(pthread_attr_t *attr);int pthrea ...
- Linux多线程实践(3) --线程属性
初始化/销毁线程属性 int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *att ...
- 线程属性 pthread_attr_t
参考资料: https://blog.csdn.net/hudashi/article/details/7709413 Posix线程中的线程属性pthread_attr_t主要包括scope属性.d ...
- Unix线程概念、控制原语、属性
线程: 线程基础概念: 线程在Linux中又称轻量级进程.而且它和进程都有PCB(进程控制块).可是差别是进程的虚拟地址空间是独享的,也就是每一个进程都有自己的虚拟地址空间.可是线程的PCB是共享的, ...
- UNIX环境编程学习笔记(27)——多线程编程(二):控制线程属性
lienhua342014-11-09 1 线程属性概括 POSIX 线程的主要属性包括 scope 属性.detach 属性.堆栈地址.堆栈大小.优先级.在头文件 pthread.h 中定义了结构体 ...
随机推荐
- linux 连接wifi
前言 我使用树莓派的时候实际过的. 正文 第一步扫描wifi: iwlist wlan0 scan 然后配置: vim /etc/wpa_supplicant/wpa_supplicant.conf ...
- Lattice下载器高速编程器HW-USBN-2B fpga仿真器ispdown烧录器
1.概述 HW-USBN-2B 编程烧录Lattice所有芯片,速度非常快.支持Lattice FPGA芯片在线稳定仿真.烧录.加密,支持Lattice CPLD烧录.支持外部配置FLASH.PROM ...
- 鸿蒙HarmonyOS实战-ArkUI组件(Canvas)
一.Canvas Canvas组件是一种图形渲染组件,它提供了一个画布(canvas),开发者可以在上面绘制各种图形.文本等.Canvas组件通常用于创建游戏.数据可视化等需要动态绘制图形的应用程序. ...
- Python数据分析 Series 笔记
002,pandas介绍 003,Series创建 导入Pandas Series 是一种类似于一维数组的对象,由下面两个部分组成: values:一组数据(ndarray类型) index:相关的数 ...
- 【力扣精选】Oracle SQL 176. 第二高的薪水
[力扣精选]Oracle SQL 176. 第二高的薪水 这道题很适合用来作为窗口函数的入门使用练习 链接如下: https://leetcode.cn/problems/second-highest ...
- 力扣436(java&python)-寻找右区间(中等)
题目: 给你一个区间数组 intervals ,其中 intervals[i] = [starti, endi] ,且每个 starti 都 不同 . 区间 i 的 右侧区间 可以记作区间 j ,并满 ...
- 在阿里巴巴,我们如何先于用户发现和定位 Kubernetes 集群问题?
简介:本文整理自阿里云高级研发工程师彭南光(光南) 在 KubeCon China 2021 大会的演讲实录,分享了阿里巴巴是如何通过自研通用链路探测+定向巡检工具 KubeProbe 应对大规模集 ...
- 自建Kubernetes集群如何使用弹性容器实例ECI
简介: 虚拟节点(Virtual Node)实现了Kubernetes与弹性容器实例ECI的无缝连接,让Kubernetes集群轻松获得极大的弹性能力,而不必受限于集群的节点计算容量.您可以灵活动态的 ...
- Kettle on MaxCompute使用指南
简介: Kettle是一款开源的ETL工具,纯java实现,可以运行于Windows, Unix, Linux上运行,提供图形化的操作界面,可以通过拖拽控件的方式,方便地定义数据传输的拓扑.Kett ...
- Pull or Push?监控系统如何选型
简介: 对于建设一套公司内部使用的监控系统平台,相对来说可选的方案还是非常多的,无论是用开源方案自建还是使用商业的SaaS化产品,都有比较多的可选项.但无论是开源方案还是商业的SaaS产品,真正实施 ...