SwiftUI中NavigationLink引发无限循环问题求助
问题现象
在SwiftUI开发中,某一个NavigationLink触发了无限循环,具体表现为ViewAViewModel的init方法被反复调用(控制台持续输出VIEW A INIT)。该问题仅在iOS 18.2.1真机上出现,iOS 18.0模拟器无此异常。即使移除ViewAView和ViewAViewModel中的所有可观测性代码,问题依然存在。将视图模型的创建从计算属性移至主视图的init方法后,无限循环问题消失。
相关代码
主视图body代码
var body: some View { List { viewA } .listStyle(.insetGrouped) .navigationTitle(viewModel.game.teamName) .navigationBarTitleDisplayMode(.inline) }
NavigationLink相关代码
private var viewA: some View { CustomNavigationLink { ViewAView(viewModel: viewModel.viewAViewModel) } label: { Text("View A") } }
计分卡管理器视图模型定义(原计算属性)
var viewAViewModel: ScorecardManagerViewModel { ViewAViewModel(game: game) }
ViewA视图模型初始化方法
init(game: Game) { self.game = game self.scenarios = game.scenariosAsArray() ?? [] shouldShowInitialAddScenario() updateCampaignScore() print("VIEW A INIT") }
CustomNavigationLink实现
struct CustomNavigationLink<Destination, Label>: View where Destination : View, Label : View { var destination: () -> Destination let label: () -> Label var body: some View { HStack { label() Spacer() Image(systemName: "chevron.right") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 7) .fontWeight(.bold) .foregroundColor(.purple) } .background( NavigationLink { destination() } label: { Text("") } .opacity(0) ) } }
问题原因
核心问题在于视图模型的计算属性定义:每次访问viewModel.viewAViewModel都会创建一个全新的ViewAViewModel实例。在iOS 18.2.1真机的SwiftUI渲染机制下,NavigationLink的目标视图闭包被频繁求值(可能是系统对视图布局、状态的检查逻辑发生了变化),导致计算属性被反复触发,进而不断初始化ViewModel,形成无限循环。
解决方案
- 将视图模型改为存储属性:在主视图的ViewModel初始化时提前创建
ViewAViewModel,并存储为实例属性,避免每次访问都生成新对象:
class MainViewModel { let game: Game let viewAViewModel: ScorecardManagerViewModel init(game: Game) { self.game = game // 提前初始化视图模型,仅创建一次 self.viewAViewModel = ViewAViewModel(game: game) } }
- 确认闭包求值时机:如果自定义
CustomNavigationLink的destination闭包存在被重复调用的可能,可以考虑用@autoclosure修饰参数,优化闭包的执行时机,但当前问题的核心还是视图模型的创建方式。
内容的提问来源于stack exchange,提问作者TheMile133
相关产品推荐
相关产品推荐

