SwiftUI从CoreData加载图片列表在Xcode+iOS17下的性能问题
SwiftUI视图在iOS 17 + Xcode 15.2下的性能异常问题
问题代码
import SwiftUI struct ImagesView : View { @Environment(\.managedObjectContext) private var objectContext @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Photo.date, ascending: true)], animation: .default) private var photos: FetchedResults<Photo> @State private var gridHeight = 180.0 var body: some View { VStack { ScrollView(.horizontal) { LazyHGrid(rows: [GridItem(.fixed(gridHeight))], alignment: .top, spacing: 0) { ForEach(photos) { photo in if let data = photo.filteredData { Image(data: data) .resizable() .scaledToFit() } } } .frame(height: 200) } } } }
异常现象
- iOS 16.x设备上运行一切正常
- iOS 17.x设备通过Xcode 15.2运行时,打开该视图所在标签页及滚动图片时,应用需要很长时间才能恢复响应
- 控制台会打印大量会话相关日志(见下方)
- 直接在iOS 17.x设备上运行(不通过Xcode)则无异常
控制台日志
[0x10a022200] Created session [0x10a025600] Created session [0x10a028a00] Created session [0x0] Releasing session [0x0] Releasing session [0x10612b600] Releasing session [0x10a030200] Releasing session [0x10a028a00] Releasing session [0x10a022200] Releasing session [0x0] Releasing session [0x0] Releasing session [0x106151c00] Created session [0x10615bc00] Created session [0x106151c00] Releasing session [0x0] Releasing session [0x10706da00] Created session [0x107091800] Created session [0x10706da00] Releasing session [0x0] Releasing session [0x10b858c00] Created session
用户疑问
- 上述代码是否存在严重性能问题?
- 为何通过Xcode运行会产生延迟?
- 这些iOS日志的成因是什么?
问题解答
一、代码是否存在严重性能问题?
现有代码没有致命性能问题,但存在可优化的细节:
LazyHGrid的外部frame(height: 200)和内部GridItem(.fixed(gridHeight))(180)高度不一致,会触发额外的布局计算开销- 直接从Core Data的
filteredData初始化Image,未做图片解码缓存,滚动时会重复执行解码操作,iOS 17的渲染管道对这类重复操作的敏感度更高 - 未对
FetchedResults做分页或批量加载,若照片数量极大,会一次性加载所有数据,加重内存与渲染负担
这些问题在iOS 16中未暴露,说明iOS 17的SwiftUI/UIKit渲染机制有调整,但代码本身不属于“严重性能问题”范畴。
二、为何通过Xcode运行会产生延迟?
延迟源于Xcode调试器的附加带来的额外开销:
- Xcode 15在调试iOS 17设备时,会开启对渲染会话的追踪功能,这些追踪操作会占用CPU资源,当大量图片快速渲染时,调试器的追踪开销被放大,导致UI卡顿
- 直接在设备上运行时,无调试器附加,这类追踪逻辑不会触发,因此性能正常
- iOS 17的渲染框架对图片加载的会话管理做了调整,Xcode 15的调试工具对这些会话的日志输出更密集,进一步加剧了调试时的性能损耗
三、这些日志的成因是什么?
日志中的Created session/Releasing session是iOS 17中图片渲染会话的生命周期记录:
- 每加载一张图片,系统会创建临时渲染会话,用于图片解码、纹理上传到GPU,渲染完成后释放该会话
- 在Xcode调试模式下,系统会输出这些会话的创建/释放日志,Release模式或无调试器附加时默认不会打印
- 滚动时快速加载大量图片,导致短时间内创建/释放大量会话,从而产生密集的日志输出
内容的提问来源于stack exchange,提问作者meaning-matters
相关产品推荐
相关产品推荐

