我已经将Swift编译器标志-warn-long-function-bodies
设置为90毫秒,以查看我的项目中哪些函数需要太长时间来编译(由于类型检查)。
我有以下方法:
func someKey(_ sectionType: SectionType, row: Int) -> String {
let suffix = row == 0 ? "top" : "content"
return "\(sectionType)_\(suffix)"
}
(SectionType
是一个基于字符串的枚举)
如上所述,在 2017 年款 MacBook Pro 上花费了 96 毫秒。我尝试的第一件事是绕过字符串插值,改用 \(sectionType.rawValue)
而不是 \(sectionType)
,但现在它给出了 106 毫秒。走错了路...
接下来,我做了以下更改:
let suffix = row == 0 ? "top" : "content"
to:
let suffix = "top"
警告消失了,因此是三目运算符引起了问题。
我尝试使用以下方法代替:
let suffix: String = { // Note the type annotation!
if row == 0 {
return "top"
}
return "content"
}()
...但现在是闭包需要 97 毫秒 (整个函数,101 毫秒)。
我甚至尝试了更明确的写法:
let suffix: String = {
if row == 0 {
return String("top")
} else {
return String("content")
}
}()
...然后我得到了闭包: 94ms; 函数: 98ms。
发生了什么?
我的90毫秒限制太低了吗?我知道字典字面量存在(或者说仍然存在)类型检查错误,但这似乎完全不同...?
我的环境是Xcode 8.3.2 (8E2002),Swift: Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
但等等!还有更多...
我尝试了这个函数体:
func someKey(_ sectionType: SectionType, row: Int) -> String {
if row == 0 {
return "\(sectionType.rawValue)_top"
} else {
return "\(sectionType.rawValue)_content"
}
}
...并且它需要97ms~112ms!?
补充:我将函数和枚举移植到一个干净、最小的项目(Single View Application)中设置了相同的警告,但没有发生。我确定整个项目在某种程度上影响了这个方法,但还不能确定具体是如何影响的...
补充2:我测试了我的函数的静态版本:无论row
的值为何,都使用固定后缀“top”(这需要少于90毫秒,并且不会触发任何警告),但是添加了以下if
块:
func someKey(_ sectionType: SectionType, row: Int) -> String {
if row == 0 {
print("zero")
} else {
print("non-zero")
}
let suffix: String = "top"
return "\(sectionType)_\(suffix)"
}
这让我想起了96~98毫秒!所以,当将行与零进行比较时,问题就出现了?
解决方法:我一直在尝试我的代码,不知怎么的,我发现如果我用switch语句替换if块,问题就解决了。
func someKey(_ sectionType: SectionType, row: Int) -> String {
let suffix: String = {
switch row {
case 0:
return "top"
default:
return "content"
}
}()
return "\(sectionType)_\(suffix)"
}
我不会回答自己的问题,因为我认为这并不是真正发生的事情的解释。
let suffix: String = ...
会发生什么? - Fogmeisterreturn“Hello, world!”
,会发生什么呢?只是为了检查它是第一行还是最后一行的插值。 - FogmeisterString("top")
(可能是因为构造器重载的原因)