【潮汐】鴻蒙ArkUI中的LazyForEach和SwiftUI中的ForEach有什么區(qū)別

鴻蒙HarmonyOS開發(fā)ArkUI中的LazyForEach和SwiftUI中的ForEach的區(qū)別

SwiftUI 提供了三種不同的機(jī)制來構(gòu)建一棵樹的動(dòng)態(tài)部分,F(xiàn)orEach就是其中之一。
ArkUI是鴻蒙的核心UI布局框架,除了ForEach,它還提供了LazyForEach,便于高性能開發(fā)。

image.png

由于ForEach往往和List搭配使用,我們會(huì)關(guān)注ForEach里的view是不是懶加載的,在SwiftUI中,只有ForEach,沒有公開資料描述ForEach加載方式,在WWDC20-10031的材料中提到過:List里的內(nèi)容總是以懶加載方式存在的。

然而測試發(fā)現(xiàn),當(dāng)list里的數(shù)據(jù)到達(dá)100000條后,初始化CPU占有率會(huì)達(dá)到100%,此時(shí)頁面雖然顯示了,但是無法滑動(dòng),即無響應(yīng)狀態(tài)。

List {
    ForEach(0..<100000){ I in
        ChatView(id: i)
    }
}

why is the swiftUI list not lazy (compared to lazyVStack)?
Bad performance of large SwiftUI lists on macOS

一種優(yōu)化方式是給 List 里的內(nèi)容加上固定高度,這樣使用ForEach時(shí)SwiftUI就不需要計(jì)算每一個(gè)內(nèi)容的高度了。

List {
    ForEach(0..<100000){ I in
        ChatView(id: i)
            .frame(width: 500, height: 15, alignment: .leading)
    }
}

此外,SwiftUI提供了LazyVStack和LazyHStack這兩個(gè)容器,放在這兩個(gè)容器中的內(nèi)容是懶加載的。

相比SwiftUI,ArkUI中的LazyForEach無法實(shí)現(xiàn)以下場景:

1、SwiftUI中,可以使用ForEach直接遍歷,可以通過$0獲取索引。

VStack() {
    // 遍歷從1-10,并創(chuàng)建從1-10的文本組件
    ForEach((1...10), id: \.self) {
        Text("\($0)…")
    }
}

2、可以直接對(duì)數(shù)組進(jìn)行forEach,進(jìn)行遍歷:

let name = ["a","b","c","d"]

name.forEach {
    switch $0 {
    // 對(duì)name進(jìn)行遍歷,找到a
    case let x where x.hasPrefix("a"):
        print("\(x) is here")
    default:
        print("hi, \($0)")
    }
}
SwiftUI和ArkUI中的LazyForEach使用差異如下:

1、自由控制遍歷的次數(shù)

在SwiftUI中,比如用數(shù)組的前一半數(shù)據(jù)繪制Text:

ForEach(0..<foo.count/2) { index in
    Text(foo[index])
}

在ArkUI中,以下代碼報(bào)錯(cuò):Argument of type ‘boolean’ is not assignable to parameter of type ‘a(chǎn)ny[]’.

ForEach(0..<foo.count/2,
  (item, index) => {
    ListItem() {
      Stack50View()
    }
  },
  (item) => item.toString()
)

2、List和ForEach搭配使用靈活性

在SwiftUI中,List中可以提供多個(gè)數(shù)據(jù)源和ForEach組合,比如在List中添加一組ForEach,添加一個(gè)Text后再添加一組ForEach:

List{
  ForEach(items,id:\.self){ item in
    Text(item)
  }
  Text("其他內(nèi)容")
  ForEach(0..<10){ I in
    Text("id:\(i)")
  }
}

在ArkUI中,List中只能添加ListItem,以下代碼報(bào)錯(cuò):The ‘List’ component can have only the ListItem, Section and ListItemGroup child component.

List() {
  Text()
  ForEach(this.arr,
    (item, index) => {
      ListItem() {
        Stack50View()
      }
    },
    (item) => item.toString()
  )
  ForEach(this.arr,
    (item, index) => {
      ListItem() {
        Stack50View()
      }
    },
    (item) => item.toString()
  )
}

其他

SwiftUI中 ForEach內(nèi)對(duì)數(shù)據(jù)增、刪、改、查不需要通知框架層。
ArkUI中的LazyForEach需要告知框架層。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容