适合基础入门级面试准备:
1. Swift中let和var的区别是什么?
答案:let用于定义常量,一旦赋值后不可修改;var用于定义变量,赋值后可以修改。
2. 什么是可选类型(Optional)?
答案:可选类型用于表示一个值“可能存在,也可能不存在(nil)”,通过在类型后加?声明(如String?)。它是Swift处理“值缺失”的安全方式。
3. 如何安全解包可选类型?
答案:常用方式有两种:
• 可选绑定(if let/guard let):if let value = optionalValue { ... }
• nil合并运算符(??):let result = optionalValue ?? defaultValue
避免使用强制解包(!),否则当值为nil时会崩溃。
4. 结构体(Struct)和类(Class)的核心区别是什么?
答案:
• 结构体是值类型(赋值时复制数据),类是引用类型(赋值时复制引用,共享数据);
• 结构体无继承,类支持继承;
• 结构体默认生成“成员初始化器”,类需手动定义初始化器。
5. Swift的switch语句与Objective-C的switch有何不同?
答案:
• Swift的switch默认不穿透(无需写break);
• 支持多种类型(字符串、枚举、范围等),不局限于整数;
• 可通过where子句添加额外条件。
6. 什么是尾随闭包(Trailing Closure)?
答案:当函数的最后一个参数是闭包时,可将闭包写在函数括号外,简化代码。例如:
func doSomething(completion: () -> Void) { ... }
// 尾随闭包写法
doSomething {
print("完成")
}
7. 值类型和引用类型的本质区别是什么?
答案:
• 值类型(如struct、enum、String、Array):赋值/传参时复制完整数据,各自修改不影响对方;
• 引用类型(如class):赋值/传参时复制引用地址,多个变量指向同一块内存,修改会相互影响。
8. 如何定义一个接收可变数量参数的函数?
答案:使用可变参数符号...,参数会被当作数组处理。例如:
func sum(numbers: Int...) -> Int {
return numbers.reduce(0, +)
}
sum(1, 2, 3) // 结果为6
9. 什么是元组(Tuple)?
答案:元组是临时存储多个不同类型值的集合,可用于快速返回多个值。例如:
let person = (name: "Alice", age: 25)
print(person.name) // 输出 "Alice"
10. guard语句的作用是什么?
答案:guard用于“提前退出”,当条件不满足时执行else块并退出当前作用域,可简化嵌套判断。例如:
func checkAge(age: Int?) {
guard let age = age, age >= 18 else {
print("年龄不合法")
return
}
print("年龄合法")
}
11. 数组(Array)和集合(Set)的区别是什么?
答案:
• 数组:有序,元素可重复,通过索引访问;
• 集合:无序,元素不可重复(需遵循Hashable协议),适合去重或快速查找。
12. 什么是枚举(Enum)?
答案:枚举是定义一组相关值的类型,可用于替代魔法数字或字符串,增强代码可读性。例如:
enum Direction {
case north, south, east, west
}
13. 如何给枚举添加原始值?
答案:定义枚举时指定原始值类型,并为成员赋值。例如:
enum Weekday: String {
case monday = "Mon"
case tuesday = "Tue"
}
print(Weekday.monday.rawValue) // 输出 "Mon"
14. 什么是初始化器(Initializer)?
答案:初始化器是类/结构体创建实例时调用的方法,用于初始化所有存储属性。结构体默认生成“成员初始化器”,类需手动实现。
15. 类的“指定初始化器”和“便利初始化器”有何区别?
答案:
• 指定初始化器(Designated Initializer):类的主要初始化器,必须初始化所有存储属性,用init定义;
• 便利初始化器(Convenience Initializer):辅助初始化器,必须调用同一类的指定初始化器,用convenience init定义。
16. 什么是可选链(Optional Chaining)?
答案:通过?.访问可选类型的属性/方法,若链中任意环节为nil,整个表达式结果为nil,避免嵌套可选绑定。例如:
let length = person?.address?.street?.count // 若任意环节为nil,结果为nil
17. nil合并运算符(??)的作用是什么?
答案:如果可选类型有值,则解包并返回该值;如果为nil,则返回默认值。例如:
let username = inputName ?? "Guest" // 若inputName为nil,用"Guest"
18. Swift中的String是值类型还是引用类型?
答案:String是值类型(本质是结构体),但Swift通过“写时复制(Copy-on-Write)”优化性能,避免不必要的复制。
19. 什么是扩展(Extension)?
答案:扩展用于在不修改原有代码的情况下,为已有类型(如Int、String、自定义类)添加方法、计算属性等。例如:
extension Int {
func squared() -> Int { return self * self }
}
3.squared() // 结果为9
20. 如何判断两个引用类型实例是否指向同一对象?
答案:使用===运算符(值相等用==)。例如:
let obj1 = Person()
let obj2 = obj1
print(obj1 === obj2) // 输出 true
21. 字典(Dictionary)的键需要满足什么条件?
答案:字典的键必须遵循Hashable协议,因为字典通过哈希值快速查找键对应的value。
22. 什么是闭包(Closure)?
答案:闭包是自包含的代码块,可捕获和存储外部变量,类似匿名函数。例如:
let add = { (a: Int, b: Int) -> Int in
return a + b
}
add(2, 3) // 结果为5
23. 闭包的捕获列表(Capture List)有什么用?
答案:指定闭包对外部变量的捕获方式(如weak、unowned),用于避免循环引用。例如:
class Person {
var name: String
init(name: String) { self.name = name }
lazy var printName: () -> Void = { [weak self] in
print(self?.name ?? "nil")
}
}
24. 用let定义的数组可以添加元素吗?
答案:不能。let定义的数组是不可变数组(长度和元素都不能修改);需用var定义可变数组才能添加/删除元素。
25. 什么是计算属性(Computed Property)?
答案:计算属性不存储值,而是通过getter(获取值)和setter(设置值)计算值。例如:
struct Rectangle {
var width: Double
var height: Double
var area: Double {
get { return width * height }
set { width = newValue / height }
}
}
26. 存储属性(Stored Property)和计算属性的区别?
答案:
• 存储属性:直接存储值,占用内存空间;
• 计算属性:不存储值,通过getter/setter计算,不占用内存。
27. for-in循环可以遍历哪些类型?
答案:可遍历所有遵循Sequence协议的类型,如数组、集合、字典、范围(1...5)、字符串等。
28. 如何将字符串转换为整数?
答案:使用Int的初始化器,返回可选类型(转换失败为nil)。例如:
let num = Int("123") // 结果为Optional(123)
let invalidNum = Int("abc") // 结果为nil
29. 什么是范围(Range)?
答案:范围表示两个值之间的区间,常见两种:
• 闭区间(a...b):包含a和b(如1...5表示1、2、3、4、5);
• 半开区间(a..<b):包含a,不包含b(如1..<5表示1、2、3、4)。
30. Swift的访问控制修饰符有哪些?
答案:从严格到宽松依次为:
• private:仅当前作用域可见;
• fileprivate:当前文件内可见;
• internal:默认修饰符,模块内可见;
• public:模块外可访问,但不可继承/重写;
• open:模块外可访问,且可继承/重写。
这些题目覆盖了Swift基础核心,适合快速梳理入门级知识点,面试前可重点记忆。