我没有得到有用的信息“不应在主线程上调用此方法,因为它可能导致 UI 无响应。”来自 Xcode 的紫色警告,但 UI 非常缓慢。我将如何追踪它的来源?
在我的天真中,我添加了一些代码来像这样将自己插入 runloop
private var previousTimeInSeconds: Double = 0
private var previousLogInSeconds: Double = 0
private lazy var displayLink: CADisplayLink = {
let displayLink = CADisplayLink(target: self,
selector: #selector(displayLoop))
return displayLink;
}()
var watchdog: Timer?
private func startLoop() {
previousTimeInSeconds = displayLink.timestamp
displayLink.add(to: .current, forMode: .common)
}
@objc private func displayLoop() {
let currentTimeInSeconds = displayLink.timestamp
let elapsedTimeInSeconds = currentTimeInSeconds - previousTimeInSeconds
previousTimeInSeconds = currentTimeInSeconds
//let actualFramesPerSecond = 1 / (displayLink.targetTimestamp - displayLink.timestamp) // is showing constant 59.xxx FPS
let actualFramesPerSecond = 1 / elapsedTimeInSeconds
if currentTimeInSeconds - previousLogInSeconds > 1 {
NSLog("fps: \(actualFramesPerSecond)")
previousLogInSeconds = currentTimeInSeconds
}
watchdog?.invalidate()
let interval = TimeInterval(0.5)
watchdog = Timer.scheduledTimer(withTimeInterval: interval, repeats: false) { [weak self] _ in
NSLog("iOS-299 main loop did not get control back in \(interval) second")
}
}
但是 NSLog("iOS-299 主循环没有得到控制权..") 在我的 ui 中切换选项卡后几秒钟内看到延迟时不会跳闸。
在我的特殊情况下,带有几十个项目的 VStack 上的 ScrollView 没有帮助。切换到 List 自然有帮助 在某种程度上
var body: some View {
List {
// ScrollView {
// VStack(spacing: 0.0) {
SomeHeavyweightHorizontalType1(models: model.carouselModels)
vvvvvv bottleneck is somewhere here vvvvvvvvv
ForEach(model.sectionsModel, id: \.title) { section in
let _ = NSLog("iOS-299 section \(section.title)")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ but this log prints twice. Why?
SomeHeavyweightHorizontalListType2(model: section)
}
// }
}
UPD:在我的例子中,这项工作是通过代码审查完成的,并将 SomeHeavyweightHorizontalListType2 中的 HStack 替换为 LazyHStack(它被包裹在一个 VStack 中,我最终改为 LazyVStack)但我想知道如果我最终没有通过 codereview 追踪到这个?
权威来源“探索UI动画故障和渲染循环”的部分答案https://developer.apple.com/videos/play/tech-talks/10855/
我运行了 Apple“Hitches”仪表盘,在我的特殊情况下,所有高严重性挂钩类型都是“预提交延迟” 然而,回溯是非常无用的,因为它们最终出现在 CoreAnimation、UIKit 和 SwiftUI 的内部结构。痕迹中没有显示我的代码。
我想必须在 UIKit 中重写麻烦的代码。