• iOS属性关键字And深浅拷贝再探究


        属性关键字是基础,所谓很细节化的东西就出在这上面了
    
    • 1

    属性关键字的划分

    • 读写权限类型的:readonly , readwrite
    • 原子类型的:atomic , nonatomic
    • 引用计数类型的:retain/strong/copy,assign/unsafe_unretained,weak

    读写权限类型readonly , readwrite

    • 所谓读写权限就是对成员是否只进行读或者读写
      • readwrite 是可读可写特性;会自动生成getter方法和setter方法
      • readonly 是只读特性 只会生成getter方法 ,不会生成setter方法

    读写的区别

    • readwrite是默认属性
      对readonly修饰的属性进行写操作会报错,但可以直接访问成员变量
    @interface ViewController ()
    @property (readonly) NSString* strOne;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        _strOne = @"iOS";
        self.strOne = @"iOS"; 错误
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    请添加图片描述

    原子类型atomic , nonatomic

    原子的理解

     原子性是指一个事物的操作是不可分割的,要么都发生,要么都不发生。
    
    • 1

    atomic- 默认线程安全

    • atomic(默认属性)原子属性,为setter方法加锁,线程安全的,效率相对低。
    • atomic描述的是属性赋值,属性赋值中还包含着很多其他操作,如访问对象,赋值等等,natomic是保证这个赋值的整个过程的完整性,并且不受其他线程的干扰,要么成功要么失败- 原子操作
    • atomic仅仅保证了属性赋值的过程是安全并不保证对属性的读写操作是安全的
    • atomic对一个数组,进行赋值或获取,是可以保证线程安全的。但是如果进行数组进行操作,比如给数据加对象或移除对象,是不在atomic的保证范围。

    nonatomic- 高效

    • nonatomic是非原子属性,线程不安全的,不会为属性的Setter方法加锁(还未了解锁),效率高 -推荐使用

    引用计数类型关键字

    retain关键字

    • retain只有在MRC的环境下使用(我理解的MRC环境就不是在当前的ARC环境下。也就是没有自动回收机制的情况下)
      retain引起对象的引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

    Strong And Weak

    • Strong 表示了指向并且拥有该对象,其修饰的对象引用计数会加1.该对象只要引用计数不为0则不会被销毁。当然强制将其置为nil也可以销毁它。
    • Weak表示了指向但不拥有该对象,其修饰的对象引用计数不变并且在程序结束的时候自行销毁,属性也会清空

    assgin

    • assgin修饰OC里基础的数据类型,int,BOOL,被修饰的对象引用计数不会发生改变,但是当assgin修饰的对象被销毁的时候该对象指向的指针指向之前的地址,成为悬垂指针,可能导致内存泄露和系统崩溃

    unsafe_unretained

    • unsafe_unretained和weak的区别在于unsafe_unretained针对的是对象类型,在其杯销毁的时候该对象nil但是属性还存在- 注意区别于weak

    Copy-深拷贝浅拷贝

    • copy 修饰的是不可变对象,而strong修饰的是可变对象
    • copy修饰不可变对象、原对象为不可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是浅复制,两个指针指向的是同一个地址。
      请添加图片描述
    @interface ViewController ()
    @property (nonatomic, copy) NSString* strOne;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        NSString* strTest = @"11111";
        _strOne = strTest;
        NSLog(@"strOne = %p, StrTest = %p", _strOne, strTest);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • copy修饰不可变对象,原对象为可变对象时,将原对象赋值给属性,会将原对象进行copy,此时是深复制,两个对象指向的不同的地址,属性所指的是可变对象的副本,原对象如果被修改的话,不会影响属性的值

    深入理解深浅Copy

    深入理解深浅Copy

    Copy修饰了可变的数组

    • NSMutableArray用copy修饰会出现什么问题?
      • 出现调用可变方法不可控问题,会导致程序崩溃。 具体原因如下:
        给Mutable 被声明为copy修饰的属性赋值, 过程描述如下:
        1.如果赋值过来的是NSMutableArray对象,会对可变对象进行copy操作,拷贝结果是不可变的,那么copy后就是NSArray
        2.如果赋值过来的是NSArray对象, 会对不可变对象进行copy操作,拷贝结果仍是不可变的,那么copy之后仍是NSArray。
        所以不论赋值过来的是什么对象,只要对NSMutableArray进行copy操作,返回的对象都是不可变的。
        那原来属性声明的是NSMutableArray,可能会调用了add或者remove方法,拷贝后的结果是不可变对象,所以一旦调用这些方法就会程序崩溃(crash)

    本文参照

    iOS属性关键字

  • 相关阅读:
    Redis数据结构——五种数据类型
    哈工大李治军老师操作系统笔记【23】:内存换出(Learning OS Concepts By Coding Them !)
    Ubuntu编译AOSP Android9
    李沐老师 PyTorch版——线性回归 + softmax回归的简洁实现(3)
    AIX7.1安装Oracle11g补丁33829709(PSU+OJVM)
    深度学习中的normalization总结(BN、LN、WN、IN、GN)
    Windows卸载ninja流程
    4.mybatis 高级结果查询
    Linux下设置网关以及网络相关命令
    【ROS2原理14】.msg / .srv / .action文件的做法
  • 原文地址:https://blog.csdn.net/weixin_61639290/article/details/126253936