MST
星途 面试题库

面试题:在Objective-C中,使用copy属性修饰NSString和NSMutableString时会有什么不同表现,为什么?

假设有一个类,其中有一个属性用copy修饰,分别传入NSString和NSMutableString对象,描述对象赋值过程中的内存变化,以及这样设计的意义,包括可能涉及到的深拷贝和浅拷贝概念。
44.6万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. 传入NSString对象时内存变化

  • 赋值过程:当把一个NSString对象赋值给用copy修饰的属性时,实际发生的是浅拷贝。因为NSString本身是不可变的,系统为了优化性能,不会重新开辟内存创建一个新的字符串对象。而是让属性直接指向传入的NSString对象,引用计数加1。
  • 内存变化:没有新的内存分配用于存储字符串内容,只是属性的指针指向了已有的NSString对象,对象的引用计数增加。

2. 传入NSMutableString对象时内存变化

  • 赋值过程:当把一个NSMutableString对象赋值给用copy修饰的属性时,发生的是深拷贝。系统会创建一个新的NSString对象(因为用copy修饰后属性的类型是不可变的NSString),并将NSMutableString的内容复制到新创建的对象中。
  • 内存变化:会开辟新的内存空间来存储新创建的NSString对象及其内容,新对象的引用计数为1,而原NSMutableString对象不受影响,引用计数不变。

3. 这样设计的意义

  • 数据保护:使用copy修饰属性可以防止外部对对象内部数据的意外修改。比如如果属性是一个字符串,当传入一个可变的NSMutableString时,若没有copy操作,外部仍然可以修改这个字符串,可能导致对象内部状态的不一致。而通过copy操作,属性持有一个不可变的副本,保证了数据的安全性。
  • 遵循不可变原则:在很多情况下,对象的某些属性应该是不可变的,以确保对象状态的稳定性和可预测性。使用copy可以确保属性值一旦确定就不会被意外改变。

4. 深拷贝和浅拷贝概念

  • 浅拷贝: 只复制指向对象的指针,而不复制对象本身,新旧对象共享同一块内存。就像传入NSString对象时,属性只是指针指向原对象,并没有复制对象内容。
  • 深拷贝:会创建一个全新的对象,并将原对象的内容复制到新对象中,新旧对象位于不同的内存位置。如传入NSMutableString对象时,会创建新的NSString对象并复制内容。