《iOS之一起进大厂》系列-iOS属性关键字和相关的面试题

2,162 阅读7分钟

前面的话

属性关键字是iOS开发中的基础。 基础往往容易被忽略,但是细节决定成败。 如果面试时,忽然来一发属性关键字相关的问题,回答的不好,那给面试官的印象就会差很多,成为了木桶短板的一个。可能前面回答的好建立的优势就没了。

在这里插入图片描述
在这里插入图片描述

开始面试

我正在会议室略有紧张的等待面试,忽然看到一个穿着格子衬衫,大腹便便的中年男子拿着简历向我走来, 我看着他头上快要绝顶的头发,心想这肯定是个iOS开发技术牛逼闪闪的老前辈。 还好看过杯子写《iOS之一起进大厂》系列,我的知识很渊博,基础很牢固,不慌。刚紧张到提到嗓子眼的心,又按下去了。淡定从容,一点都不虚好伐,就是这么自信淡定。

我什么时候也能变成那样厉害的高手

变强了
变强了

面试官:

小伙子,看你简历 ,你对开发基础了解的很透彻啊,那咱们今天就聊聊属性关键字把。 你对属性关键字怎么理解?

属性关键字可以分为三种类型:

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

读写权限的类型: readonly ,readwrite

  • readwrite 是可读可写特性;会自动生成getter方法和setter方法
  • readonly 是只读特性 只会生成getter方法 ,不会生成setter方法

原子类: atomic nonatomic

atomic是保证赋值和获取是线程安全的。 这里说的是对成员属性的直接赋值和获取,并代表操作和访问。 对于atomic的属性,系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。

retain关键字

只有在MRC的环境下使用。 retain引起对象的引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

那你说说strong和weak的区别是?

strong 表示指向并拥有该对象。其修饰的对象引用计数会加1.该对象只要引用计数不为0则不会被销毁。当然强制将其置为nil也可以销毁它。 weak 表示指向但不拥有该对象。其修饰的对象引用计数不会增加。无需手动设置,该对象会自行在内存中销毁。

如何理解的atomic的线程安全呢,有没有什么隐患?

atomic对一个数组,进行赋值或获取,是可以保证线程安全的。但是如果进行数组进行操作,比如给数据加对象或移除对象,是不在atomic的保证范围。

strong 和weak的区别?

strong 表示指向并拥有该对象。其修饰的对象引用计数会加1.该对象只要引用计数不为0则不会被销毁。当然强制将其置为nil也可以销毁它。 weak 表示指向但不拥有该对象。其修饰的对象引用计数不会增加。无需手动设置,该对象会自行在内存中销毁。

assign 和weak的区别有哪些?

assign修饰基础数据类型,int, BOOL assign修饰对象类型,不改变对象的引用计数。 assign 会产生悬垂指针, assign 的对象被释放之后,对象指针还是会指向原来的地址,会产生悬垂指针 ,导致程序内存泄露和程序崩溃。

weak不改变修饰对象的引用计数 所指向的对象在被释放后自动设置为 nil. 他们的区别: 1、assign可以修饰对象和基本数据类型, weak只修饰对象
2、assign 所修饰的对象被释放后,还会指向原对象内存地址。weak 所修饰的对象被废弃之后,weak 所修饰对象会被设置为nil。 但是他们有一个共同点,他们都不会改变修饰对象的引用计数。

copy关键字影响了对象的可变和不可变属性吗?

可变对象(mutable)copy和mutableCopy都是深拷贝 不可变对象(immutable)的copy是浅拷贝,mutableCopy是深拷贝 copy方法返回的都是不可变对象,若被拷贝对象是可变对象,返回的也是不可变对象。 例子解析如下:

浅拷贝和深拷贝的区别?

浅拷贝只是对 内存地址的复制,两个指针指向同一个地址,增加被拷贝对象的引用计数,没有发生新的内存分配。 深拷贝:目标对象指针和源对象指针,指向两片内容相同的内存空间。
2个特点:不会增加被拷贝对象的引用计数,产生了新内存分配,出现了2块内存。 总结区别: 浅拷贝增加引用计数,不产生新的内存。 深拷贝不增加引用结束,会新分配内存

NSMutableArray用copy修饰会出现什么问题?

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

MRC下如何重写retain修饰变量的setter方法?

这里关键点在于,如果恰好设置的是原来的对象,不做判断的话,就会导致把自己对象给释放了,会导致程序访问异常。所以需要先做判断。

weak属性修饰的变量,如何实现在变量没有强引用后自动置为 nil ?

runtime 维护了一个weak_table_t 弱引用表 ,用于存储指向某一个对象的所有weak指针。weak表其实是一个哈希表, key是所指对象的地址,value是weak指针的地址的数组。

在对象回收的时候,根据对象的地址将所有weak指针地址的数组,遍历数组把其中的数据置为nil

__weak 和 _Unsafe_Unretain 的区别?

weak 修饰的指针变量,在指向的内存地址销毁后,会在 Runtime 的机制下,自动置为 nil。 _Unsafe_Unretain不会置为 nil,容易出现 悬垂指针,发生崩溃。但是 _Unsafe_Unretain 比 __weak 效率高。

坚持看到这里的同学,你们个个都是人才,我好喜欢。

创作不易,大家好我是空杯子,文章每周持续更新,如果这个文章写得还不错,觉得杯子 我有写的东西对你有点用的话 ,请给我点赞👍 关注❤分享

白嫖不好, 跪求 点关注,加收藏,求分享

如果本篇博客有任何错误,请批评指教,不胜感激 !

在微信中搜索 「 空杯子One 」 或扫描下面二维码 第一时间阅读和催更(比博客早一到两篇哟),还可以获取整理好的最全的iOS面试题、答案和iOS学习资料。 本文在GitHub github.com/schelling/i… 做成集合,那有一线大厂面试点思维导图,也整理了很多我的博客文档,欢迎Star和完善,大家面试可以参照考点复习,一起学而时习之,不亦说乎。