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

Swift跨类/ViewModel/View共享同步Realm及解决线程读写问题

问题描述

我正尝试将所有业务逻辑拆分至各类Manager(如RealmManager),并通过ViewModel类调用以展示UI,类间数据通过Combine保持实时更新。具体而言,我需在UI中展示由独立于ViewModel的类管理的同步Realm上的实时User对象。

但始终遇到Realm引用及读写操作的线程相关问题,崩溃信息如下:

Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.'

核心问题:如何分离同步Realm的创建与订阅变更管理,实现跨类写入及UI端读取?


相关代码

RealmManager类

public class RealmManager: NSObject {
    static var shared: RealmManager = RealmManager()
    var realm: Realm?
    var realmUserID: String?

    func setupRealm(authToken: String) async throws {
        guard let user = await getRealmUser() else { // this loads the realm user
            print("couldn't get realm user")
        }
        self.realmUserID = user.id
        
        // setup sync subscriptions & realm
        guard let realm = self.setupRealmSubscriptions(user: user) else { // this loads the realm
            print("couldn't add subs / setup realm")
        }
        // this function does this using Realm(configuration: flexSyncConfig)
        self.realm = realm


        AccountManager.shared.loadOwnUser()
    }
}

(setupRealm()会在外部完成认证逻辑后调用)

AccountManager类

public class AccountManager: NSObject, ObservableObject {

    static var shared: AccountManager = AccountManager()

    @Published var ownUser: User?

    func loadOwnUser() {
        guard let realmUserId = RealmManager.shared.realmUserID else {
            print("AccountManager setup failed")
        }
        let ownUser = User(_id: realmUserId) // user object that will be displayed in UI, see struct below
            do {
                try realm.write {
                    realm.add(ownUser)
                }
                DispatchQueue.main.async {
                    self.ownUser = ownUser
                }
            } catch {
                print("oups!")
            }
    }
}

ViewModel类

class ViewModel: ObservableObject {
    private var cancellables = Set<AnyCancellable>()
    @Published var ownUser: User?

    init() {
        loadUser()
    }

    func loadUser() {
        RealmManager.shared.$ownUser
            .sink { completion in print("Completed with \(completion)")
                } receiveValue: { [weak self] ownUser in
                    DispatchQueue.main.async {
                        self?.ownUser = ownUser
                    }
                }
            .store(in: &cancellables)
    }
}

View类

struct TestView: View {
    
    @ObservedObject var viewModel: ViewModel // passed from a view controller that this TestView lives in
    
    var body: some View {
        if let ownUser = viewModel.ownUser {
            Text(ownUser._id)
        }
    }
}

User模型类

class User: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var _id = UUID().uuidString
    convenience init(_id: String? = nil) {
        self.init()
        if let _id = _id {
            self._id = _id
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:35:42