我们正在使用领域,并且想要分离领域
Object
,即:创建对象的静态副本,该对象是一个 swift 类/结构,并且可以独立于领域传递和修改。我们需要这个有两个主要原因:
Object
甚至导入RealmSwift包。如何实现这一目标?
我看到两个“解决方案”,每个解决方案都有其不理想的原因(请参阅下面的代码):
方法 1 将领域对象映射到值类型并手动编写所有 CRUD 操作,这些操作也在它们之间进行映射。 这篇文章做了类似的事情。但是,这两篇文章都非常古老(4+和6+年)并且已经过时(根据领域文档:“
@Persisted
声明样式取代了旧版本的@objc dynamic
声明符号” SDK 的版本。")
方法 2 创建“DetachableObject”协议并为
Object
创建符合该协议的扩展,就像这里。但这篇文章已经有7年历史了,并没有真正解决上面所说的原因1。
方法1
public struct Publisher {
public let identifier: Int
public let name: String
}
final class PublisherObject: Object {
dynamic var identifier = 0
dynamic var name = ""
override static func primaryKey() -> String? {
return "identifier"
}
}
extension Publisher: Persistable {
public init(managedObject: PublisherObject) {
identifier = managedObject.identifier
name = managedObject.name
}
public func managedObject() -> PublisherObject {
let publisher = PublisherObject()
publisher.identifier = identifier
publisher.name = name
return publisher
}
}
// more see: https://gist.github.com/gonzalezreal/9d297c68435b9ee12bb1b009afd41d9a
方法2
protocol DetachableObject: AnyObject {
func detached() -> Self
}
extension Object: DetachableObject {
func detached() -> Self {
let detached = type(of: self).init()
for property in objectSchema.properties {
guard let value = value(forKey: property.name) else { continue }
if let detachable = value as? DetachableObject {
detached.setValue(detachable.detached(), forKey: property.name)
} else {
detached.setValue(value, forKey: property.name)
}
}
return detached
}
}
extension List: DetachableObject {
func detached() -> List<Element> {
let result = List<Element>()
forEach {
result.append($0.detached())
}
return result
}
}
我相信您正在询问 Realm 对象的非托管版本。
如果是这样,就是这个过程:创建、对象并持久化它
class Person: Object {
@Persisted var name = ""
}
let p = Person()
p.name = "Jay"
try! realm.write {
realm.add(p)
}
稍后,我们想要 Jay 的非托管副本 - 它不与领域绑定,不生活也不反映 jay 的任何更改,并且仅生活在内存中
let jay = realm.objects(Person.self).where { $0.name == "Jay" }.first!
let unmanagedJay = Person(value: p)
//unmanagedJay is not Persisted and is flexible for doing what's needed with that object
这应该满足以下要求:1) 完全抽象持久层,然后 2) 能够传递这些对象
我们在 macOS 应用程序中经常使用此过程,将对象的非托管副本放置在 UI 中向用户显示的工作表中,该工作表可以自由操作,而不会影响 Realm 或受 Realm 影响