換)
先把結(jié)論放在前面:@Composable函數(shù)不是"普通函數(shù)加了注解",而是被編譯器插件改寫過(guò)的函數(shù)——它把"描述 UI 的代碼"變成"向運(yùn)行時(shí)描述樹(shù)(SnapshotTree)注冊(cè)一份描述",運(yùn)行時(shí)由 Composition 負(fù)責(zé)組合、狀態(tài)變化時(shí)按需重組。 理解這一點(diǎn),就理解了 Compose 的各項(xiàng)特性:為什么沒(méi)有控件引用、為什么重組可以跳過(guò)、為什么副作用需要單獨(dú)聲明。面試官驗(yàn)證 Compose 入門的真實(shí)功力有個(gè)土辦法:聊坑。默認(rèn)行為是什么、邊界在哪、出錯(cuò)時(shí)是什么表現(xiàn)。背資料的人在這里會(huì)集體沉默。 所以這篇的重點(diǎn)放在三個(gè)必答的坑上。編譯期與運(yùn)行時(shí)的分工@Composable函數(shù)的處理分兩個(gè)階段:編譯期(Compose Compiler Plugin):檢查@Composable調(diào)用只能出現(xiàn)在@Composable上下文(這就是"Composable 函數(shù)只能從 Composable 函數(shù)調(diào)用"這條限制的來(lái)源)生成"重組作用域"標(biāo)記($composer、$changed標(biāo)記當(dāng)前函數(shù)依賴了哪些狀態(tài))把狀態(tài)讀取位置編譯成"依賴注冊(cè)"——val x by state會(huì)被轉(zhuǎn)成"當(dāng)前重組作用域訂閱了state