初级 iOS 开发面试题:Swift、UIKit 与 SwiftUI

Milad Bonakdar
作者
练习初级 iOS 面试常见问题,涵盖 Swift、UIKit、SwiftUI、网络、数据持久化和异步代码,并提供清晰回答思路。
引言
初级 iOS 开发面试通常会考察你是否能解释 Swift 基础、用 UIKit 或 SwiftUI 构建简单界面、请求并解码数据、选择基本的本地存储方式,以及避免常见的内存和线程问题。好的回答应该简短、具体,并能说明你会如何构建一个小型 App。
使用本指南练习入门 iOS 岗位最常见的问题:概念是什么意思、什么时候使用,以及初级开发者需要注意什么风险。
Swift 基础 (6 个问题)
1. Swift 中 var 和 let 有什么区别?
答案:
var: 声明一个可变变量。它的值在初始化后可以更改。let: 声明一个不可变常量。一旦设置,其值不能更改。- 最佳实践: 默认情况下使用
let以确保安全性和清晰度。仅在您知道该值将更改时才使用var。
稀有度: 非常常见 难度: 简单
2. 解释 Swift 中的可选类型(Optionals)。什么是可选绑定(Optional Binding)?
答案:
可选类型表示一个可能为 nil(缺少值)的值。
- 声明: 在类型后使用
?:var name: String? - 解包方法:
- 强制解包:
name!(危险,如果为 nil 会崩溃) - 可选绑定: 使用
if let或guard let安全地解包 - Nil 合并运算符:
name ?? "Default" - 可选链:
user?.address?.city
- 强制解包:
稀有度: 非常常见 难度: 简单
3. Swift 中 class 和 struct 有什么区别?
答案:
- Class: 引用类型(存储在堆上)。支持继承。通过引用传递。
- Struct: 值类型(存储在栈上)。没有继承。通过复制传递。
- 何时使用:
- Struct: 对于简单的数据模型,当您需要值语义(独立的副本)时
- Class: 当您需要继承、引用语义或析构器时
稀有度: 非常常见 难度: 中等
4. 什么是 Swift 中的闭包(Closures)?
答案: 闭包是自包含的功能块,可以在您的代码中传递和使用。它们类似于其他语言中的 lambdas 或匿名函数。
- 语法:
{ (parameters) -> ReturnType in statements } - 捕获值: 闭包可以捕获和存储对其周围上下文中变量的引用。
- 常见用途: 完成处理程序、回调、数组操作。
稀有度: 非常常见 难度: 中等
5. 解释 weak 和 unowned 引用的区别。
答案: 两者都用于防止引用循环(内存泄漏)。
weak: 可选引用,当引用的对象被释放时,会自动变为nil。当引用可能比对象寿命更长时使用。unowned: 非可选引用,假设对象将始终存在。如果在释放后访问,则会崩溃。当您确定引用不会比对象寿命更长时使用。
稀有度: 常见 难度: 中等
6. 什么是 Swift 中的协议(Protocols)?
答案: 协议定义了适合特定任务或功能的的方法、属性和其他要求的蓝图。类、结构体和枚举可以采纳协议。
- 类似于: 其他语言中的接口
- 协议扩展: 可以提供默认实现
- 面向协议编程: Swift 的首选范例
稀有度: 非常常见 难度: 简单
UIKit 基础 (5 个问题)
7. UIView 和 UIViewController 有什么区别?
答案:
UIView: 表示屏幕上的一个矩形区域。处理绘图和事件处理。示例:UILabel、UIButton、UIImageView。UIViewController: 管理一个视图层级结构。处理视图生命周期、用户交互和导航。包含一个根视图并管理其子视图。- 关系: 视图控制器管理视图。一个视图控制器可以有多个视图。
稀有度: 非常常见 难度: 简单
8. 解释视图控制器生命周期方法。
答案: 视图控制器具有按顺序调用的特定生命周期方法:
viewDidLoad(): 视图加载到内存时调用一次。需要发生一次的设置。viewWillAppear(_:): 在视图出现在屏幕上之前调用。可以多次调用。viewDidAppear(_:): 在视图出现在屏幕上之后调用。在此处启动动画。viewWillDisappear(_:): 在视图消失之前调用。viewDidDisappear(_:): 在视图消失之后调用。清理资源。
稀有度: 非常常见 难度: 简单
9. 什么是 Auto Layout,你如何使用约束(constraints)?
答案: Auto Layout 是一种基于约束的布局系统,允许您创建可在不同屏幕尺寸和方向上工作的自适应 UI。
- 约束: 定义视图之间的关系(宽度、高度、间距、对齐方式)
- 方法:
- Interface Builder: Xcode 中的可视化编辑器
- 编程方式: NSLayoutConstraint 或 NSLayoutAnchor API
- Visual Format Language: 基于字符串(现在不常用)
稀有度: 非常常见 难度: 中等
10. frame 和 bounds 有什么区别?
答案:
frame: 视图在其父视图坐标系中的位置和大小。用于定位视图。bounds: 视图在其自身坐标系中的位置和大小。原点通常是 (0, 0)。用于在视图内部绘制内容。- 主要区别:
frame相对于父视图,bounds相对于自身。
稀有度: 常见 难度: 中等
11. 如何处理来自 UITextField 的用户输入?
答案: 存在多种方法:
- Target-Action: 为
.editingChanged事件添加 target - Delegate: 遵循
UITextFieldDelegate协议 - Combine: 使用 publishers(现代方法)
稀有度: 非常常见 难度: 简单
SwiftUI 基础 (4 个问题)
12. 什么是 SwiftUI,它与 UIKit 有何不同?
答案:
SwiftUI 是 Apple 的声明式 UI 框架。你根据状态描述界面,状态变化时 SwiftUI 会更新渲染后的视图。UIKit 是命令式的,你会直接创建和修改 UIView、UILabel、UIViewController 等对象。
在初级面试中,不要把它说成 SwiftUI 已经完全替代 UIKit。很多生产 App 会同时使用两者。更好的回答是:SwiftUI 适合新页面和状态驱动的 UI,代码更简洁;UIKit 在旧代码库、自定义控件以及 SwiftUI 尚未完整覆盖的 API 中仍然重要。
稀有度: 非常常见 难度: 简单
13. 解释 SwiftUI 中的 @State、@Binding 和 @ObservedObject。
答案: 这些属性包装器说明状态存放在哪里,以及谁可以修改它。
@State: 由某个 View 拥有的私有状态,通常用于简单的本地 UI 状态。@Binding: 指向父 View 所拥有状态的双向连接。子 View 可以读写它,但不拥有它。@ObservedObject: 指向外部可观察模型数据的引用。当数据由其他对象拥有,而 View 需要随数据变化刷新时使用。较新的 SwiftUI 代码中也会看到 Observation framework 和@Observable,但很多面试仍会问这些包装器。
稀有度: 常见 难度: 中等
14. 如何在 SwiftUI 中创建一个列表?
答案:
使用 List 视图来显示可滚动的数据集合。
稀有度: 常见 难度: 简单
15. 什么是 SwiftUI 中的视图修饰符(View Modifiers)?
答案: 视图修饰符是创建具有修改属性的新视图的方法。它们是可链接的。
- 常用修饰符:
.padding()、.background()、.foregroundColor()、.font()、.frame() - 顺序很重要: 修饰符按顺序应用
稀有度: 常见 难度: 简单
数据与网络 (5 个问题)
16. 如何在 iOS 中发出网络请求?
答案:
使用 URLSession。在现代 Swift 中,初级回答可以展示 async/await,并说明旧代码库中仍可能使用 completion handler。更接近实际开发的回答还会验证 HTTP 响应、处理错误、解码为 Codable 模型,并在 main actor 上更新 UI。
稀有度: 非常常见 难度: 中等
17. Swift 中的 Codable 是什么?
答案:
Codable 是 Encodable & Decodable 协议的类型别名。它允许在 Swift 类型和外部表示(如 JSON)之间轻松转换。
- 自动合成: 如果所有属性都是 Codable,Swift 会自动生成编码/解码代码。
- 自定义键: 使用
CodingKeys枚举来映射不同的属性名称。
稀有度: 非常常见 难度: 简单
18. 如何在 iOS 中本地持久化数据?
答案: 本地数据持久化有多种选择:
- UserDefaults: 用于少量数据的简单键值存储(设置、首选项)
- 文件系统: 将文件保存到 Documents 或 Cache 目录
- Core Data: Apple 的对象图管理和持久化框架
- SQLite: 关系数据库
- Keychain: 用于敏感数据的安全存储(密码、令牌)
稀有度: 非常常见 难度: 简单
19. 同步和异步操作有什么区别?
答案:
同步操作会阻塞当前线程,直到操作完成。如果在主线程上执行,App 可能会失去响应。异步操作会启动任务并让当前线程继续执行,结果稍后通过 async/await、completion handler、delegate 或 publisher 返回。
在 iOS 面试中,要把这个概念和 UI 响应性联系起来:网络请求、文件操作和重计算不应该阻塞 main thread,UI 更新应在 main actor 上执行。
稀有度: 常见 难度: 简单
20. 什么是 Grand Central Dispatch (GCD)?
答案: GCD 是 Apple 用于把任务调度到 dispatch queue 的底层 API。main queue 用于 UI 工作,global queue 可以按不同 QoS 优先级执行后台任务。
在较新的 Swift 代码中,通常会优先使用 Swift concurrency(async/await、Task 和 actor),因为它让异步代码更易读。但 GCD 仍然重要,因为许多 UIKit 项目、旧代码库以及基于 callback 的 API 仍会使用 DispatchQueue.main.async 或后台队列。
稀有度: 常见 难度: 中等


