Part 2 — Swift 高级 & 并发

一、Swift 内存 & 值语义(★★★★★)

Q21:struct 和 class 本质区别?
struct 是 值类型,存储在栈或 inline storage 中,赋值时发生 copy。
class 是 引用类型,存储在堆上,变量保存的是指针。
核心区别:
struct → 值语义
class → 引用语义
✅ 值语义带来线程安全
✅ 避免共享状态
Swift 优先推荐 struct 是为了 predictable state。

Q22:什么是 Copy-on-Write(COW)?
Copy-on-Write 是一种 延迟复制优化:

  • 多个变量共享同一内存
  • 当发生写操作时才真正复制
var a = [1,2,3]
var b = a   // 未复制
b.append(4) // 此时复制

通过 isKnownUniquelyReferenced 判断引用唯一性。
为什么 Swift Array 性能高?
因为 COW 避免不必要复制。

Q23:struct 一定在栈上吗?
struct 不一定在栈上,它的存储位置由编译器决定,可能在栈、堆甚至寄存器中。比如作为局部变量时通常在栈上,但如果作为 class 的成员或者被闭包捕获,可能会分配在堆上。本质上,struct 的核心是值语义,而不是具体的内存位置,这一点和 class 的引用语义是本质区别

Q24:mutating 关键字作用?
因为 struct 是值类型。
mutating 表示:方法内部允许修改 self。
本质:
self = newSelf

二、Swift Dispatch 机制(🔥 高频杀手)

类型 dispatch
class override dynamic
protocol extension static
final static
generic static

Q26:protocol extension 为什么可能不走重写?
protocol extension 默认是 static dispatch。
只有 protocol requirement 才是 dynamic dispatch。

protocol A {
    func test()
}

extension A {
    func test() { print("A") }
}

调用取决于类型声明方式。
Swift 优先静态派发提升性能。

三、Closure(★★★★★)

Q27:closure 捕获变量还是值?
捕获的是变量引用(capture by reference)。

var a = 10
let c = { print(a) }
a = 20
c() // 20

Q28:[weak self] 原理?
closure 捕获:

weak reference -> side table

避免 closure strong 持有 self。
capture list 在 closure 创建时执行。

Q29:escaping closure 是什么?
closure 生命周期逃离当前函数作用域。
例如:

  • 网络回调
  • async 执行

为什么需要标记?
因为:
编译器需要改变内存管理策略。

四、泛型(8 年高频)

Q30:泛型优势?

  • 代码复用
  • 类型安全
  • 编译期检查
  • 无 runtime casting

Q31:associatedtype 是什么?
用于 protocol 中定义占位类型。

protocol Container {
    associatedtype Item
}

Q32:为什么不能直接用带 associatedtype 的 protocol?
因为:
编译器无法确定具体类型大小。
所以需要:
👉 Type Erasure

Q33:什么是 Type Erasure?
把具体泛型类型隐藏为统一类型。

AnySequence
AnyPublisher

核心思想:
用 box 包装真实类型。
一句话:
抹去泛型信息以统一接口。

五、Swift Concurrency(现在面试必问)

Q34:async/await 解决什么问题?

  • callback hell
  • 可读性差
  • 错误传播困难
  • 让异步代码像同步代码。

Q35:async/await 本质是多线程吗?
是协程(cooperative concurrency)。
任务可挂起,不阻塞线程。

Q36:Task 是什么?
Task 是 Swift 并发的基本执行单元。
类似轻量级协程。

Q37:Task 和 GCD 区别?

Task GCD
结构化并发 手动管理
自动取消传播
async/await callback

Q38:什么是 Structured Concurrency?
子任务生命周期绑定父任务。
父取消 → 子全部取消。

Q39:Actor 为什么线程安全?
Actor 内部状态一次只允许一个任务访问。

actor mailbox queue

串行执行。
一句总结:
Actor = async + serial queue + state isolation

Q40:MainActor 作用?
保证代码运行在主线程。

@MainActor
class ViewModel {}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容