You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI获取Firebase UID触发紫色警告及内存占用过高问题排查

问题分析与解决方案

代码存在的核心问题

  1. 触发无限视图更新循环:你的GetUid()方法在返回值的同时修改了@Published var userID,如果这个方法在SwiftUI视图的body计算过程中或视图更新回调里被调用,修改@Published属性会立刻触发视图重新渲染,而视图重新渲染又可能再次调用该方法,形成无限循环。这就是紫色警告的来源,同时无限循环会持续占用内存,最终导致内存耗尽。
  2. 冗余设计:方法既要返回UID又要更新Published属性完全没必要——Published属性本身就是用来向视图传递数据的,不需要额外返回值。

修复方案

方案1:初始化时一次性获取UID

修改ObservableObject的初始化方法,在对象创建时就获取并设置UID,避免反复调用触发更新:

import SwiftUI
import Firebase

class GetUidFromFirebase: ObservableObject{
    @Published var userID: String = ""
    
    init() {
        // 初始化时获取一次UID
        userID = Auth.auth().currentUser?.uid ?? ""
    }
}

在视图里只需观察这个userID即可,无需主动调用方法。

方案2:监听Firebase Auth状态变化(更可靠)

如果用户可能在使用过程中登录/登出,应该监听Auth的状态变化,自动更新UID,而非手动调用方法:

import SwiftUI
import Firebase

class GetUidFromFirebase: ObservableObject{
    @Published var userID: String = ""
    private var handle: AuthStateDidChangeListenerHandle?
    
    init() {
        // 监听Auth状态变化
        handle = Auth.auth().addStateDidChangeListener { [weak self] auth, user in
            self?.userID = user?.uid ?? ""
        }
    }
    
    deinit {
        // 销毁时移除监听,避免内存泄漏
        if let handle = handle {
            Auth.auth().removeStateDidChangeListener(handle)
        }
    }
}

这种方式会自动在用户登录、登出时更新userID,不会触发无限循环,同时在对象销毁时移除监听,避免额外内存占用。

视图中的正确使用方式

在视图里创建ObservableObject实例并观察,不要在body里调用修改Published属性的方法:

struct ContentView: View {
    @StateObject private var uidManager = GetUidFromFirebase()
    
    var body: some View {
        Text("当前用户UID:\(uidManager.userID)")
    }
}

内容的提问来源于stack exchange,提问作者Tracy9988 Xu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:41:06