一、接上一篇《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 属性和线程安全的更多相关文章

  1. 线程的属性和 线程特定数据 Thread-specific Data

    一.posix 线程属性 POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者可以访问和修改的线程属性.主要包括如下属性: 1. 作用域(scope) 2. 栈尺 ...

  2. C# 的界面控件属性修改线程安全问题

    今天在实验delegate与thread 在初步的实验结束后,因为原来的delegate只有一个函数会被调用,感觉没有达到delegate的极致,所以又重新自己定义了一个delegate,在另一个线程 ...

  3. 线程属性总结 线程的api属性

    http://blog.csdn.net/zsf8701/article/details/7842392 //线程属性结构如下:typedef struct{ int etachstate; //线程 ...

  4. 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程

    进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...

  5. python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02

    目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...

  6. pthread_attr_t 线程属性(二)

    一.函数: 1.线程属性的初始化与销毁:#include <pthread.h>int pthread_attr_init(pthread_attr_t *attr);int pthrea ...

  7. Linux多线程实践(3) --线程属性

    初始化/销毁线程属性 int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *att ...

  8. 线程属性 pthread_attr_t

    参考资料: https://blog.csdn.net/hudashi/article/details/7709413 Posix线程中的线程属性pthread_attr_t主要包括scope属性.d ...

  9. Unix线程概念、控制原语、属性

    线程: 线程基础概念: 线程在Linux中又称轻量级进程.而且它和进程都有PCB(进程控制块).可是差别是进程的虚拟地址空间是独享的,也就是每一个进程都有自己的虚拟地址空间.可是线程的PCB是共享的, ...

  10. UNIX环境编程学习笔记(27)——多线程编程(二):控制线程属性

    lienhua342014-11-09 1 线程属性概括 POSIX 线程的主要属性包括 scope 属性.detach 属性.堆栈地址.堆栈大小.优先级.在头文件 pthread.h 中定义了结构体 ...

随机推荐

  1. nginx重新整理——————静态服务[四]

    前言 简单介绍一下nginx的静态服务. 正文 一般静态服务一般是alias 和 root. 就是上面这个哈. 那么root和alias 的区别是啥呢? 比如root: 然后修改一下就是: 如果这样配 ...

  2. Python阿里云消息推送调用API

    很多公司测试APP推送时候,应该也是很头疼:推送环境:测试.正式,稍不注意就把测试的push到正式上,导致所有用户都收到 例子很多: 其实阿里.极光都有推送Api,直接调用API就ok,特别是有的公司 ...

  3. 力扣455(java&python)-分发饼干(简单)

    题目: 假设你是一位很棒的家长,想要给你的孩子们一些小饼干.但是,每个孩子最多只能给一块饼干. 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸:并且每块饼干 j,都有 ...

  4. 免费体验!阿里云智能LOGO帮你解决设计难题

    ​简介:超实用!零基础搞定一个高大上的智能logo设计 新年过后,往往是大家一年中士气最足的时候,散去了年末的疲惫和emo,重燃对新一年的热情和希望. 想创业的朋友们同样意气风发,趁着新年的劲头想大干 ...

  5. [FAQ] CodeLlama GGUF 文件下载

    hf-mirror: https://hf-mirror.com/TheBloke/CodeLlama-7B-GGUFmodelscope: https://modelscope.cn/models/ ...

  6. [Pholcus] Go项目 Pholcus 源码逻辑分析 species.go

    「代码结构」 结构体:蜘蛛种类列表(即:蜘蛛规则列表) 变量:全局蜘蛛种类实例 方法:向蜘蛛种类清单添加新种类 方法:获取全部蜘蛛种类 方法:通过名字获取蜘蛛 「总体功能」 添加新种类:通过 Spid ...

  7. [Go] golang 执行 Linux 系统 command

    执行系统 shell 命令示例: fileDir := "files/"out, err := exec.Command("sh", "-c" ...

  8. WPF 引用 UWP 控件 不打包为 MSIX 分发的方法

    按照微软的官方文档,大部分的文档都会说如果用了 XAML Islands 等技术的时候,需要新建一个打包项目,将 WPF 应用打包为 msix 等才可以进行分发和使用.但是实际上不打包也可以,此时可以 ...

  9. OLAP系列之分析型数据库clickhouse单机版部署(一)

    一.概述 官网:https://clickhouse.com/docs/zh ClickHouse是Yandex于2016年开源的列式存储数据库(DBMS),主要用于在线分析处理查询(OLAP),能够 ...

  10. vue应用el-tabel封装

    <template> <div class="table"> <el-table :data="tableList" style= ...