最近我注意到卷轴的性能正在放缓。我找到了问题,我发现原因是使用UIFont(descriptor:size:)构造函数创建的字体。我改变了UIFont(name:size:)的构造函数,我的问题得到了解决。
我在project中隔离了问题。代码是:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var firstLabel: UILabel!
@IBOutlet weak var secondLabel: UILabel!
@IBAction func onStartTest(sender: AnyObject) {
startMeasurement()
let firstFont = UIFont(name: "Marker Felt", size: 16)
firstLabel.font = firstFont
finishMeasurement("UIFont(name)")
startMeasurement()
let secondFontDescriptor = UIFontDescriptor(name: "Marker Felt", size: 16)
let secondFont = UIFont(descriptor: secondFontDescriptor, size: 16)
secondLabel.font = secondFont
finishMeasurement("UIFont(descriptor)")
}
}
private var time: UInt64 = 0
public func startMeasurement() {
time = mach_absolute_time()
}
public func finishMeasurement(name: String) {
let duration = mach_absolute_time() - time
print("* \(name) \(duration)ns")
}
这些是我的一些衡量标准:
iPhone 4S - iOS 9.0.2
* UIFont(name) 111,300ns
* UIFont(descriptor) 112,420,263ns
iPhone 6S - iOS iOS 9.2
* UIFont(name) 134,247ns
* UIFont(descriptor) 17,047,707ns
Simulator - iOS 9.2
* UIFont(name) 1,971,106ns
* UIFont(descriptor) 485,208,205ns
Simulator - iOS 8.1
* UIFont(name) 9,946,584ns
* UIFont(descriptor) 1,957,802,431ns
我做错了吗?
答案 0 :(得分:5)
我在2018年的WWDC问了一位工程师,他基本上告诉了我这个:
描述符非常昂贵,因为它们每次都在搜索ENTIRE系统字体库以获得您提供的特性。他告诉我,这个搜索确实没有优化,所以永远不应该在滚动的情况下使用,应该只调用一次然后缓存。它是这样做的,因为你实际上并不需要指定字体名称,而只是指定它的各种特性,系统会为你提供一些东西。
然而, UIFont(name: size:)
非常快,因为它直接转到系统中请求的字体。它知道字体的位置,因为您已经给出了完整的确切名称,然后它可以缩放它。没有其他不错的功能。
它大致是O(n)操作与O(1)