注册

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
}


0 个评论

要回复文章请先登录注册