美文网首页
常用的知识点总结-属性修饰符

常用的知识点总结-属性修饰符

作者: 赖晓嘉LMT | 来源:发表于2018-07-27 12:08 被阅读0次

属性修饰符

访问权限

  • readonly 只读权限
  • readwrite 可读可写权限

线程安全

  • atomic 原子性 注:atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的
@property (atomic,strong) NSString *testa;//正确
@property (noatomic,strong) NSString *testa;//错误
//atomic 保证setter getter 安全
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<10000000; i++) {
            dispatch_async(queue, ^{
                @autoreleasepool {
                    self.testa = [NSString stringWithFormat:@"testssss%zd",i];
                    NSLog(@"%@",self.testa);
                }
            });
        }
    });
//但保证不了对self.testa 进行其他操作的安全性
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<10000000; i++) {
            dispatch_async(queue, ^{
                if (i%2==0) {
                    self.testa =  @"aaaaaaaaaaaa";
                } else {
                    self.testa =  @"aaaaa";
                }
            });
        }
    });
    dispatch_async(queue, ^{
        NSString *str = [self.testa substringWithRange:NSMakeRange(0, 7)];
    });
  • nonatomic 非原子性 读写速度比atomic快,原因是不涉及线程安全的判断以及对应的操作

指定方法名称

  • getter=method 指定get方法名
  • setter=method 指定set方法名

内存管理

  • retain 一般是在MRC下用来修饰对象,修饰对象为强引用,使其引用计数+1,保证对象不被销毁,只要还有一个变量指向对象.对象就会保持在内存中.当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放.
  • assign 一般用来修饰基本数据类型,修饰对象为弱引用,而且不会将已经释放的指针值nil,容易引起野指针问题,在 set 方法中 ARC 系统不会调用 引用计数器相关的代码执行, 只是简单的赋值而已,计数器不会改变.其为非OC对象.
  • strong 和retain 但是,是在ARC下修饰对象的.在 set 方法中 ARC 系统会自动帮我们加入对 新值 retain 使其引用计数器 + 1 的代码,并且对旧 值进行 release 使其引用计数器 - 1 的代码.
  • weak 同样是出现在ARC下修饰对象的,修饰对象为弱引用,在 set 方法中 ARC 系统不会调用 引用计数器相关的 代码执行,只是简单的赋值而已,所以其引用计数器不会改变.其为OC对象。用weak修饰对象时安全的,因为用weak修饰过的对象,在对象被释放时,会将指向对象的指针置nil,避免了野指针的问题.
    补充: weak置nil 是怎么实现的?
    weak属性的特点:
    weak 表明该属性定义了一种“非拥有关系” (nonowning relationship)。
    为weak属性设置新值时,设置方法既不保留新值,也不释放旧值。
    同assign类似,然而在属性所指的对象释放时候,属性值也会清空(nil out)。
    runtime是如何实现 weak 变量的自动置nil?
    weak 对象会放入一个 hash 表中。
    用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc。
    假如 weak 指向的对象内存地址是addr,那么就会以addr为键, 在这个 weak 表中搜索,找到所有以addr为键的 weak 对象,从而设置为 nil。
    具体机制:
    objc_storeWeak(&weakPo, Model)函数:
    objc_storeWeak函数把赋值对象(Model)的内存地址作为键值key,将weak修饰的属性变量(weakPo)的内存地址(& weakPo)作为value,注册到 weak 表中。
    如果Model为0(nil),那么把变量(weakPo)的内存地址(& weakPo)从weak表中删除,
    可以把objc_storeWeak(&weakPo, Model)理解为:objc_storeWeak(value, key),并且当key变nil,将value置nil。
    在Model非nil时,weakPo和Model指向同一个内存地址,在Model变nil时,weakPo变nil。此时向weakPo发送消息不会崩溃:在Objective-C中向nil发送消息是安全的。
  • copy 拷贝了一份相同的内容,在 set 方法中 ARC 系统会自动帮我们加入对 新值 copy 的代码。引用计数器不变.
    未完待续...

相关文章

网友评论

      本文标题:常用的知识点总结-属性修饰符

      本文链接:https://www.haomeiwen.com/subject/pfywmftx.html