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
相关产品推荐
相关产品推荐

