iOS property关键字详解

栏目: IOS · 发布时间: 4年前

内容简介:补充atomic是自旋锁,即当上一线程没有执行完毕(被锁住),下一线程会一直等待(不会进入睡眠状态),当上一线程执行完毕,下一线程立即执行。他区别于互斥锁,互斥锁在等待的时候,会进入睡眠状态,当上一个线程执行完毕,睡眠状态就会被唤醒,然后再执行。

property 属性关键字我们在日常的开发中经常会用到,所以我们有必要对其有充分的了解,这样对于我们日常开发使用时就能做到知其所以然。 ####property关键字介绍 property 关键字分为四类:

  1. 原子性: atomicnonatomicproperty 中默认是 atomic ,也就是线程安全,但是我们一般使用的是 nonatomic 。因为 atomic 的线程安全系统资源开销相对较大,影响性能,即使我们需要使用线程安全,我们也可以使用其他方法实现。atomic实现原理是在 gettersetter 中使用 @synchronized 同步锁关键字进行代码块锁定而实现的。

补充atomic是自旋锁,即当上一线程没有执行完毕(被锁住),下一线程会一直等待(不会进入睡眠状态),当上一线程执行完毕,下一线程立即执行。他区别于互斥锁,互斥锁在等待的时候,会进入睡眠状态,当上一个线程执行完毕,睡眠状态就会被唤醒,然后再执行。

  1. 引用计数相关: assignretainweakstrongcopy 、iOS5以前使用的 unsafe_unretainedassign :主要修饰基本数据类型,不能修饰对象类型,如 NSInterger , CGFloat 等类型。并且统一由系统栈进行内存管理。 retain :修饰对象类型,强引用对象,并是对象引用计数加1,可用于 MRC 环境中。 weak :修饰对象类型,对对象弱引用,不增加对象的引用计数。如果对象销毁了,指针会自动指向 nil ,所以可以防止野指针的问题。 strong :修饰对象类型,对对象强引用,会增加对象的引用计数。如果指向了空对象,会造成野指针。只能用于 ARC 环境。 copy :在一个新对象引用计数为1,赋值时对传入值进行一份拷贝,所以才使用copy关键字。你将一个对象赋值给一个属性,该属性并不会持有对象,而是会创建一个新对象,并将这个对象拷贝给它。使用 copy 关键字的对象必须实现 NSCoding 协议。 unsafe_unretained :跟 weak 类似,声明一个弱引用,区别是当引用计数为0时,变量不会自动设置为 nil

  2. 读写权限相关:默认是 readwrite (可读可写),还有readonly,修饰属性时,属性不能被外界修改。

  3. 方法名:可设置属性的 settergetter 方法名。 ####补充介绍 weak 关键字

  • 使用场景 用于一些对象互相引用时,避免出现互相强引用而导致的循环引用,对象不能释放的。
  • 实现原理 weak 修饰时, runtime 会维护一个 hash 表(也称为 weak 表),用于存储对象的所有 weak 指针, hash 表的 key 是该对象的地址, valueweak 指针的地址(这个地址的值是所指对象的地址)数组。(备注 strong 是通过 runtime 维护的一个自动引用计数表) weak 的实现原理总结:
  1. 初始化时, runtime 会调用 objc_initWeak 函数,初始化一个新的 weak 指针指向对象地址;
  2. 添加引用时, objc_initWeak 函数会调用 objc_storeWeak 函数, objc_storeWeak 的作用是更新指针指向,创建对应的弱引用表(hash表);
  3. 释放时,调用 clearDeallocating 函数。 clearDeallocating 函数首先根据对象地址获取 weak 指针地址的数组,然后遍历这个数组把其中指向空对象的指针设为 nil ,最后把这个指针从 weak 表中删除,最后清理对象的记录。

copystrong : 讲这两个字之前我们需要了解深复制和浅复制相关的只是,可以参考这里。具体示例如下:

@property (nonatomic, copy) NSMutableArray *mutArray;
NSMutableArray *mutArray1 = [NSMutableArray array];
self.mutArray = mutArray1;
复制代码

等同于

@property (nonatomic, strong) NSMutableArray *mutArray;
NSMutableArray *mutArray1 = [NSMutableArray array];
self.mutArray = [mutArray1 copy];
复制代码

经过测试之后我们知道使用copy修饰的 mutArray 数组,当调用它的 setter 方法,它会建立一个引用计数为1的新对象,然后释放旧对象。而 copy 修饰的属性赋值时经过 copy 其实已经变成了不可变数组。而使用可变数组的增、删、改、查函数是会发现找不到相关的实例方法而 crash

NSString 为什么用 copy 而不用 retain我们通过实例来看看:

@property (nonatomic, retain) NSString *string;
NSMutableString *string1 = [[NSMutableString alloc] initWithString:@"abc"];
self.string = string1;
[string1 appendString:@"123"];
NSLog(@"==============  %@ =========", self.string);
2019-06-19 17:08:58.114333+0800 ThinTableVIew1[96955:2656816] ==============  abc123 =========

复制代码

从打印的信息可以看到当改变 string1 的值时, self.string 的值也改变了。下面我们通过查看 string 属性 setter 方法的实现来探究一下原理:

@property (nonatomic, retain) NSString *string;

- (void)setString:(NSString *)string {
    if (_string != string) {
        [_string release];
        _string = [string retain];
        //相当于
        //[string retain];
        //_string = string;
    }
}
==================
@property (nonatomic, copy) NSString *string;

- (void)setString:(NSString *)string {
    if (_string != string) {
        [_string release];
        _string = [string copy];
    }
}
复制代码

我们可以知道:

  • 当使用 retain 修饰 string 时调用的是 _string = [string retain] ,这样只会增加string的引用,而 _string 指针和 string 是指向同一块内容。所以改变 string 的内容同样的会改变 _string 的内容。
  • 当使用 copy 修饰 string 时,当传入的对象是可变对象时,调用的是 [string copy] ;会创建一个新的对象赋值给 _string ,所以 _stringstring 不会互相干扰,而改变 string 的内容不会影响 _string

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你必须知道的495个C语言问题

你必须知道的495个C语言问题

Steve Summit / 孙云、朱群英 / 人民邮电出版社 / 2009-2 / 45.00元

“本书是Summit以及C FAQ在线列表的许多参与者多年心血的结晶,是C语言界最为珍贵的财富之一。我向所有C语言程序员推荐本书。” ——Francis Glassborow,著名C/C++专家,ACCU(C/C++用户协会)前主席 “本书清晰阐明了Kernighan与Ritchie《The C programming Language》一书中许多简略的地方,而且精彩地总结了C语言编程......一起来看看 《你必须知道的495个C语言问题》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具