LazyView中带有SwiftUI的LPLinkView将使CPU保持在100%
如果在SwiftUI惰性视图(如LazyVStack、LazyHStack或LazyVGrid)中使用LPLinkView(包装在UIViewRepresentable中),则在链接完成获取后,cpu将保持100% 在提供的示例中,运行应用程序时不做任何更改。您将看到,在获取链接时,CPU会出现峰值,然后在加载所有链接后,CPU就会稳定下来 再次尝试运行应用程序,但将保存链接视图的VStack更改为LazyVStack。您将看到,即使在所有链接都完成抓取之后,cpu仍保持在100% 我相信这只是一个迅捷的错误。我已提交反馈(FB8879936)LazyView中带有SwiftUI的LPLinkView将使CPU保持在100%,swiftui,combine,Swiftui,Combine,如果在SwiftUI惰性视图(如LazyVStack、LazyHStack或LazyVGrid)中使用LPLinkView(包装在UIViewRepresentable中),则在链接完成获取后,cpu将保持100% 在提供的示例中,运行应用程序时不做任何更改。您将看到,在获取链接时,CPU会出现峰值,然后在加载所有链接后,CPU就会稳定下来 再次尝试运行应用程序,但将保存链接视图的VStack更改为LazyVStack。您将看到,即使在所有链接都完成抓取之后,cpu仍保持在100% 我相信这只是
导入快捷界面
导入链接演示文稿
进口联合收割机
结构PicSum:可解码、可识别{
变量id:String
var下载url:String
}
类ContentModel:ObservableObject{
@已发布的变量链接=[RichLink]()
@发布的var isLoading=false
var subscriptions=Set()
让picSumURL=URL(字符串:https://picsum.photos/v2/list?page=2&limit=10")!
func fetchLinks(){
links.removeAll()
isLoading=true
返回URLSession.shared.dataTaskPublisher(用于:picSumURL)
.map(\.data)
.decode(类型:[PicSum].self,解码器:JSONDecoder())
.flatMap{picSumArray in
出版商。合并很多(
微光阵列
.map{URL(字符串:$0.download_URL)!}
.map(self.fetchLink)
)
}
.map{RichLink(for:$0)}
.collect()
.receive(在:DispatchQueue.main上)
.删除任何发布者()
.sink(接收完成:{uu}in
打印(“已完成加载所有链接”)
self.isload=false
},receiveValue:{中的链接
self.links=链接
}).store(位于:&订阅中)
}
private func fetchLink(用于url:url)->AnyPublisher{
让metadataProvider=LPMetadataProvider()
回报未来{承诺未来}
DispatchQueue.main.async{
metadataProvider.startFetchingMetadata(for:url){(元数据,错误)位于
如果让元数据=元数据{
承诺(结果、成功(元数据))
}否则,如果let error=error{
承诺(结果、失败(错误))
}否则{
法塔莱罗()
}
}
}
}.删除任何发布者()
}
}
结构ContentView:View{
@StateObject变量模型=ContentModel()
var body:一些观点{
导航视图{
滚动视图{
//更改为惰性视图(LazyVStack、LazyHStack或LazyVGrid)会导致
//即使在获取所有链接后,CPU仍将保持在100%
VStack(间距:20){
ForEach(model.links){linkin
LinkView(richLink:link)
}
}
}
.overlay(ProgressView().opacity(model.isLoading?1:0).scaleEffect(2.5))
.navigationTitle(“丰富链接”)
.工具栏{
工具栏项(位置:。导航栏栏栏){
按钮(“提取”){
model.fetchLinks()
}.disabled(型号为isLoading)
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
类RichLink:NSObject,可识别{
变量id:Int!
var元数据:LPLinkMetadata!
init(用于元数据:LPLinkMetadata){
super.init()
id=Int(日期.时间间隔IncerenceDate)
self.metadata=元数据
}
}
结构链接视图:UIViewRepresentable{
var richLink:richLink
func makeUIView(上下文:context)->LPLinkView{
guard let metadata=richLink.metadata else{
返回LPLinkView()
}
让linkView=LPLinkView(元数据:元数据)
返回链接视图
}
func updateUIView(uiView:LPLinkView,context:context){
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
import SwiftUI
import LinkPresentation
import Combine
struct PicSum: Decodable, Identifiable{
var id: String
var download_url: String
}
class ContentModel: ObservableObject{
@Published var links = [RichLink]()
@Published var isLoading = false
var subscriptions = Set<AnyCancellable>()
let picSumURL = URL(string: "https://picsum.photos/v2/list?page=2&limit=10")!
func fetchLinks(){
links.removeAll()
isLoading = true
return URLSession.shared.dataTaskPublisher(for: picSumURL)
.map(\.data)
.decode(type: [PicSum].self, decoder: JSONDecoder())
.flatMap { picSumArray in
Publishers.MergeMany(
picSumArray
.map{URL(string: $0.download_url)!}
.map(self.fetchLink)
)
}
.map{RichLink(for: $0)}
.collect()
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
.sink(receiveCompletion: {_ in
print("Finished loading all links.")
self.isLoading = false
}, receiveValue: {links in
self.links = links
}).store(in: &subscriptions)
}
private func fetchLink(for url: URL) -> AnyPublisher <LPLinkMetadata, Error> {
let metadataProvider = LPMetadataProvider()
return Future { promise in
DispatchQueue.main.async {
metadataProvider.startFetchingMetadata(for: url) { (metadata, error) in
if let metadata = metadata{
promise(Result.success(metadata))
} else if let error = error{
promise(Result.failure(error))
} else {
fatalError()
}
}
}
}.eraseToAnyPublisher()
}
}
struct ContentView: View {
@StateObject var model = ContentModel()
var body: some View{
NavigationView{
ScrollView{
//Changing to Lazy view (LazyVStack, LazyHStack, or LazyVGrid) causes
//The CPU to stay at 100% even after all links have been fetched
VStack(spacing: 20){
ForEach(model.links){ link in
LinkView(richLink: link)
}
}
}
.overlay(ProgressView().opacity(model.isLoading ? 1 : 0).scaleEffect(2.5))
.navigationTitle("Rich Links")
.toolbar{
ToolbarItem(placement: .navigationBarTrailing){
Button("Fetch"){
model.fetchLinks()
}.disabled(model.isLoading)
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
class RichLink: NSObject, Identifiable {
var id: Int!
var metadata: LPLinkMetadata!
init(for metadata: LPLinkMetadata) {
super.init()
id = Int(Date.timeIntervalSinceReferenceDate)
self.metadata = metadata
}
}
struct LinkView: UIViewRepresentable {
var richLink: RichLink
func makeUIView(context: Context) -> LPLinkView {
guard let metadata = richLink.metadata else {
return LPLinkView()
}
let linkView = LPLinkView(metadata: metadata)
return linkView
}
func updateUIView(_ uiView: LPLinkView, context: Context) {
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}