IOS面试题——Swift结构体,类,枚举(3)

一 面试题汇总

  1. 枚举是否可以递归?indirect
  2. 枚举值原始值和附加值分别是什么?内存占用怎么计算?
  3. 结构体内存占用如何计算?
  4. 结构体自定义初始化方法和自动生成的初始化方法有什么关系?
  5. 结构体能否继承?如果改变property,需要怎么做?mutating
  6. 类自动生成的初始化方法与结构体自动初始化方法有何区别?
  7. struct 与 class有什么区别?值类型和引用类型,继承,初始化方法,属性值改变
  8. 如何给结构体,类,枚举增加subscript下标?subscript可以用来做什么?

二 面试题解答(仅供参考)

2.1 枚举是否可以递归?indirect

1
2
直接递归:Swift 枚举本身不能直接递归。
递归枚举:使用 indirect 关键字,可以让枚举的某个成员包含对该枚举类型自身的引用,从而实现递归枚举。

2.2 枚举值原始值和附加值分别是什么?内存占用怎么计算?

1
2
原始值:每个枚举成员有一个固定的常量值,通常是基础数据类型(如 Int、String),内存占用固定。
附加值:每个枚举成员可以携带动态值,内存占用根据附加值的类型和大小变化,Swift 使用联合体方式存储。

2.3 结构体内存占用如何计算?

1
2
3
4
5
6
7
结构体的内存占用取决于以下几个因素:

1.成员变量的类型和大小:基本类型会占用固定的字节数,而引用类型会占用指向实例的引用(通常是 8 字节指针)。
2.对齐要求:成员会根据其对齐要求进行排列,可能会填充额外的字节。
3.引用类型成员:结构体存储引用类型成员时,仅存储指向该实例的指针,而不是实例本身。

因此,结构体的内存占用不仅由它的成员的大小决定,还受到对齐要求和引用类型成员的影响。

2.4 结构体自定义初始化方法和自动生成的初始化方法有什么关系?

1
2
3
4
5
6
7
自动生成的初始化方法:在没有自定义初始化方法的情况下,Swift会自动生成一个初始化方法,包含所有存储属性的参数。

自定义初始化方法:如果你为结构体自定义了初始化方法,编译器将不会自动生成初始化方法,
你需要手动处理所有属性的赋值工作。

自定义初始化方法与自动生成方法的关系是:
自定义方法覆盖了自动生成的方法,而且在有自定义初始化方法的情况下,自动生成的初始化方法不再可用。

2.5 结构体能否继承?如果改变property,需要怎么做?mutating

1
2
3
4
5
6
结构体不能继承,因为它是值类型。

若要 修改结构体的属性,你可以:
1.如果是 var 声明的结构体实例,可以直接修改属性。
2.通过 mutating 方法修改属性。
3.使用扩展为结构体添加修改属性的功能。

2.6 类自动生成的初始化方法与结构体自动初始化方法有何区别?

1
2
3
4
5
结构体:
自动生成的初始化方法是 成员初始化方法,初始化所有存储属性,不支持继承。

类:
自动生成的初始化方法会考虑继承关系,子类可以继承并重写父类的初始化方法,且子类需要显式调用父类的初始化方法。

2.7 struct 与 class有什么区别?值类型和引用类型,继承,初始化方法,属性值改变

1-总结对比

特性 结构体 (struct) 类 (class)
类型 值类型 引用类型
继承 不支持继承 支持继承,且支持方法重写
内存管理 自动复制(值类型) 引用计数(ARC)管理内存,可能会产生循环引用
构造器 自动生成成员初始化方法 需要手动定义初始化方法,支持父类初始化方法的调用
可变性 需要 mutating 关键字才能修改属性 可以直接修改属性,引用类型通过引用传递修改属性
生命周期 超出作用域即销毁 由引用计数管理,引用计数为零时销毁

2-何时使用

1
2
使用结构体(struct):当你希望使用值类型来避免对象之间的引用共享,尤其是在数据独立的情况下,推荐使用结构体。
使用类(class):当你需要继承、引用计数管理(ARC)、或者需要共享数据时,推荐使用类。

2.8 如何给结构体,类,枚举增加subscript下标?subscript可以用来做什么?

1
2
你可以为结构体、类和枚举都添加 subscript 来定义自定义的下标访问方式。
subscript 可以用来访问、修改集合中的元素,或者通过索引值来访问和修改对象的成员数据。

三 参考

  • 简书—Swift结构体,类,枚举