卷卷的知识- Swift 高级题解答区

3.1 一个 Sequence 的索引是不是一定从 0 开始?

不一定, 两个 for in 并不能保证都是从 0 开始, 且输出结果一致, 官方文档如下:

Repeated Access  
The Sequence protocol makes no requirement on conforming types regarding
whether they will be destructively consumed by iteration. As a
consequence, don’t assume that multiple for-in loops on a sequence
will either resume iteration or restart from the beginning:

for element in sequence {
    if ... some condition { break }
}

for element in sequence {
    // No defined behavior
}
复制代码

有些同学还是不太理解, 我写了一个demo 当作参考

class Countdown: Sequence, IteratorProtocol {
    var count: Int
    init(count: Int) {
        self.count = count
    }
    func next() -> Int? {
       if count == 0 {
           return nil
       } else {
           defer { count -= 1 }
           return count
       }
   }
}

var countDown = Countdown(count: 5)
print("begin for in 1")
for c in countDown {
    print(c)
}
print("end for in 1")
print("begin for in 2")
for c in countDown {
    print(c)
}
print("end for in 2")


最后输出的结果是:
begin for in 1
5
4
3
2
1
end for in 1
begin for in 2
end for in 2
复制代码

很明显, 第二次没有输出任何结果, 原因就是在第二次for in 的时候, 并没有将count 重置。

//

//系统方法调用
print("start----")
let numbers = [2, 3, 5, 7]
var numbersIterator = numbers.makeIterator()
while let num = numbersIterator.next() {
    print(num)
}
print("midle----")
while let num = numbersIterator.next() {
    print(num)
}
print("end----")

输出:
start----
2
3
5
7
midle----
end----
复制代码

3.2 数组都实现了哪些协议

  • MutableCollection, 实现了可修改的数组, 如 a[1] = 2\
var streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"]
streets[1] = "Butler"
print(streets[1])
         // Prints "Butler"
复制代码
  • ExpressibleByArrayLiteral, 实现了数组可以从[1, 2, 3] 这种字面值初始化的能力
let countryCodes = ["BR": "Brazil", "GH": "Ghana","JP": "Japan", "US": "United States"]
// 'countryCodes' has type [String: String]

print(countryCodes["BR"]!)
// Prints "Brazil"
复制代码

3.3 如何自定义模式匹配

\

3.4 autoclosure 的作用

自动闭包, 会自动将某一个表达式封装为闭包. 如

func autoClosureFunction(_ closure: @autoclosure () -> Int) {
   closure()
}
autoClosureFunction(1)
复制代码

3.5 编译选项 whole module optmization 优化了什么

编译器可以跨文件优化编译代码, 不局限于一个文件

3.6 下面代码中 mutating 的作用是什么

struct Person {
    var name: String {
        mutating get {
            return store
        }
    }
}
复制代码

让不可变对象无法访问 name 属性

3.7 如何让自定义对象支持字面量初始化

有几个协议, 分别是
ExpressibleByArrayLiteral 可以由数组形式初始化
ExpressibleByDictionaryLiteral 可以由字典形式初始化
ExpressibleByNilLiteral 可以由nil 值初始化
ExpressibleByIntegerLiteral 可以由整数值初始化
ExpressibleByFloatLiteral 可以由浮点数初始化
ExpressibleByBooleanLiteral 可以由布尔值初始化
1 ExpressibleByUnicodeScalarLiteral
2 ExpressibleByExtendedGraphemeClusterLiteral
3 ExpressibleByStringLiteral
这三种都是由字符串初始化, 上面两种(1,2)包含有 Unicode 字符和特殊字符\

3.8 dynamic framework 和 static framework 的区别是什么

静态库和动态库, 静态库是每一个程序单独打包一份, 而动态库则是多个程序之间共享\

3.9 为什么数组索引越界会崩溃,而字典用下标取值时 key 没有对应值的话返回的是 nil 不会崩溃

数组的对象的储蓄地址是连续的,如果越界了,那取到的地址不一定可用,所以报错。毕竟还是需要有可以信任的部分的

struct Array<Element> {
    subscript(index: Int) -> Element
}

struct Dictionary<Key: Hashable, Value> {
    subscript(key: Key) -> Value?
}
复制代码

1 数组索引访问的是一段连续地址,越界访问也能访问到内存,但这段内存不一定可用,所以会引起Crash.
2 字典的key并没有对应确定的内存地址,所以是安全的.

3. 10 一个函数的参数类型只要是数字(Int、Float)都可以,要怎么表示

让参数都遵循SignedInteger协议

func myMethod<T>(_ value: T) where T: Numeric {
    print(value + 1)
} 
    myMethod(1.11)
    myMethod(2)
 输出:
2.1100000000000003
3
复制代码

3. 11 lazy 懒加载的实现

lazy懒加载,oc中实利用get方法实现,
swift利用闭包实现.比如

private lazy var navLeftButton = { () -> UIButton in
        let btn = UIButton(type: .custom)
        btn.frame = CGRect(x: 0, y: 0, width: 50, height: 30)
        btn.setImage(UIImage(named:"back"), for: .normal)
        btn.addTarget(self, action: #selector(self.back), for: .touchUpInside)
        return btn
    }()
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享