iOS 面试题 八股文 1.4
励志背下所有的八股文
class 和 struct 的区别
class 为类, struct 为结构体, 类是引用类型, 结构体为值类型, 结构体不可以继承
不通过继承,代码复用(共享)的方式有哪些
扩展, 全局函数
Set 独有的方法有哪些?
// 定义一个 set
let setA: Set<Int> = [1, 2, 3, 4, 4]// {1, 2, 3, 4}, 顺序可能不一致, 同一个元素只有一个值
let setB: Set<Int> = [1, 3, 5, 7, 9]// {1, 3, 5, 7, 9}
// 取并集 A | B
let setUnion = setA.union(setB)// {1, 2, 3, 4, 5, 7, 9}
// 取交集 A & B
let setIntersect = setA.intersection(setB)// {1, 3}
// 取差集 A - B
let setRevers = setA.subtracting(setB) // {2, 4}
// 取对称差集, A XOR B = A - B | B - A
let setXor = setA.symmetricDifference(setB) //{2, 4, 5, 7, 9}
实现一个 min 函数,返回两个元素较小的元素
func myMin<T: Comparable>(_ a: T, _ b: T) -> T {
return a < b ? a : b
}
myMin(1, 2)
map、filter、reduce 的作用
map 用于映射, 可以将一个列表转换为另一个列表
[1, 2, 3].map{"\($0)"}// 数字数组转换为字符串数组
["1", "2", "3"]
filter 用于过滤, 可以筛选出想要的元素
[1, 2, 3].filter{$0 % 2 == 0} // 筛选偶数
// [2]
reduce 合并
[1, 2, 3].reduce(""){$0 + "\($1)"}// 转换为字符串并拼接
// "123"
组合示例
(0 ..< 10).filter{$0 % 2 == 0}.map{"\($0)"}.reduce(""){$0 + $1}
// 02468
map 与 flatmap 的区别
flatmap 有两个实现函数实现,public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
这个方法, 中间的函数返回值为一个可选值, 而 flatmap 会丢掉那些返回值为 nil 的值
例如
["1", "@", "2", "3", "a"].flatMap{Int($0)}
// [1, 2, 3]
["1", "@", "2", "3", "a"].map{Int($0) ?? -1}
//[Optional(1), nil, Optional(2), Optional(3), nil]
另一个实现public func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element] where SegmentOfResult : Sequence
中间的函数, 返回值为一个数组, 而这个 flapmap 返回的对象则是一个与自己元素类型相同的数组
func someFunc(_ array:[Int]) -> [Int] {
return array
}
[[1], [2, 3], [4, 5, 6]].map(someFunc)
// [[1], [2, 3], [4, 5, 6]]
[[1], [2, 3], [4, 5, 6]].flatMap(someFunc)
// [1, 2, 3, 4, 5, 6]
其实这个实现, 相当于是在使用 map 之后, 再将各个数组拼起来一样的
[[1], [2, 3], [4, 5, 6]].map(someFunc).reduce([Int]()) {$0 + $1}
// [1, 2, 3, 4, 5, 6]
什么是 copy on write时候
写时复制, 指的是 swift 中的值类型, 并不会在一开始赋值的时候就去复制, 只有在需要修改的时候, 才去复制.
这里有详细的说明
http://www.jianshu.com/p/7e8ba0659646
如何获取当前代码的函数名和行号
#file
用于获取当前文件文件名#line
用于获取当前行号#column
用于获取当前列编号#function
用于获取当前函数名
以上这些都是特殊的字面量, 多用于调试输出日志
具体可以看这里 apple 文档
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html
这里有中文翻译
http://wiki.jikexueyuan.com/project/swift/chapter3/04_Expressions.html
如何声明一个只能被类 conform 的 protocol
声明协议的时候, 加一个 class 即可
如
protocol SomeClassProtocl: class {
func someFunction()
}
guard 使用场景
guard 和 if 类似, 不同的是, guard 总是有一个 else 语句, 如果表达式是假或者值绑定失败的时候, 会执行 else 语句, 且在 else 语句中一定要停止函数调用
例如
guard 1 + 1 == 2 else {
fatalError("something wrong")
}
常用使用场景为, 用户登录的时候, 验证用户是否有输入用户名密码等
guard let userName = self.userNameTextField.text,
let password = self.passwordTextField.text else {
return
}