Featured image of post ObservedRealmObject的大坑!

ObservedRealmObject的大坑!

我服了。有反转。

好端端的页面怎么突然莫名闪退到上个界面?

最近在用Realm写一个SwiftUI的分账App,虽然很想用SwiftData,但只支持iOS 17+把我劝退了… 实在不想碰CoreData复杂的逻辑,只好使用RealmSwift… 但Realm也是个大坑啊…(还没写,但估计以后我也不会用了)

正文

我的代码大概是这样的:

import RealmSwift
import SwiftUI

struct SplitView: View {
    @ObservedRealmObject var split: Split
    @State private var editMember: Bool = false
    ...
    var body: some View {
	            LazyVGrid(columns: [...], content: {
            ForEach(editMember ? split.family!.allparticipants : split.participants, id: \.id) { eachman in
                Button {
                    try! rc.r.write { // rc.r is a shared Realm instance
                        if split.participants.contains(object: eachman) {
                            split.thaw()!.participants.remove(object: eachman.thaw()!)
                        } else {
                            split.thaw()!.participants.append(eachman.thaw()!)
                        }
                    }
                    
                } label: {
                    ZStack {
                        AvatarView(eachman)
                    }
                }
            }
        })
        
        Button(action: {
            editMember.toggle()
        }, label: {
            Text(editMember ? "Done" : "Edit Member")
        })
    }
}

好好的怎么就出了这档子事呢?我一修改split的内容就崩了… 但我一想,估计也不是崩了,应该是被reload结果NavigationView的处理方式就是退回上级了…

上网搜了一下,感觉跟自己猜想的差不多,并且Realm官网也提到

The @ObservedRealmObject property wrapper invalidates a view when an observed object changes.

好家伙,你直接invalidate整个大View而不是使用到它的小View是吧,好好好

虽然我不信,但是我也试了这个里面的答案,哈哈,果然不对。 如果真是这样的话,继续使用@ObservedRealmObject肯定达咩了,那我们只能另辟蹊径。

尝试

这篇文章是在尝试我的猜想之前写的。你有幸能跟我一同见证我的想法是否能成功

想法很简单:完全放弃@ObservedRealmObject,使用@ObservedResults

因为@ObservedResults不会随便invalidate一整个View,所以只会影响使用Results的子View。 尝试一下:

struct SplitView: View {
	@ObservedResults(BigBill.self) private var bigBills
	private var bigBill: BigBill {
        bigBills.filter({$0.id == bigBillId}).first!
	}
}

其它代码不动 情况依旧… 官网说

You can perform a quick write to an ObservedResults collection, and the view automatically updates itself when the observed query changes.

终究还是错付了吗…

那我倒是还有一个终极的办法… 好的终极办法也失败了。

失败

详情请看我服了爸爸:NavigationBar和ToolBar修饰符到底该放在哪里啊???

对于作者来说算是彩蛋

卧槽,等一下,原来是这样吗? 我终于知道为什么之前在制作阁楼的时候每当新添加一个东西,其他的View的动画也开始改变了…原来你小子就是罪魁祸首啊 // 好的你小子不是。再见。

仅允许跳转至本网站的链接引用。未经授权不得转载、复制或用于任何形式的商业或非商业用途。
使用 Hugo 构建
主题 StackJimmy 设计