gpt4 book ai didi

ios - 为什么每次访问我的关系对象时都会重新初始化?

转载 作者:行者123 更新时间:2023-11-30 13:56:11 25 4
gpt4 key购买 nike

我使用 Realm Swift 0.95.3。在我的项目中,我正在与联系人(不是联系人 AddressBook)合作,其中包含有关姓名、姓氏、中间名、电子邮件等信息和照片。

我创建了一个名为 Contact 的 Object 子类。我了解图像或任何其他二进制数据不应存储在 Realm 中。特别是我的图像可能足够大~5 Mb。

无论如何,我想将图像存储在文件系统中,而 Realm 仅存储该图像的链接。我想将来我可能需要将其他文件(音频、PDF……)附加到 Object 的子类中。所以我决定创建一个单独的类File,它继承自Object。整个结构如下。

class File: Object {
dynamic var objectID = NSUUID().UUIDString

private var filePath: String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0] as NSString
return documentsDirectory.stringByAppendingPathComponent(objectID)
}

lazy var fileData: NSData? = {
return self.readFile()
}()

override static func primaryKey() -> String? {
return "objectID"
}

override static func ignoredProperties() -> [String] {
return ["fileData"]
}

override func copy() -> AnyObject {
let result = File(value: self)
result.objectID = NSUUID().UUIDString
result.fileData = fileData?.copy() as? NSData
return result
}
}

extension File {
//MARK:-
private func readFile() -> NSData? {
let lFilePath = filePath
print("Try to read file \(lFilePath)")
return NSData(contentsOfFile: lFilePath)
}

private func writeFileWithFileData() {
if let lFileData = fileData {
lFileData.writeToFile(filePath, atomically: true)
print("File \(filePath) was created")
} else {
removeFile()
}
}

private func removeFile() {
do {
try NSFileManager.defaultManager().removeItemAtPath(filePath)
print("File \(filePath) was removed")
} catch {
print(error)
}
}
}

如您所见,当尝试获取属性fileData时,将从文件系统接收数据。而且fileData是用关键字lazy声明的,也就是说,我希望从磁盘请求数据缓存在这个属性中。如果这个属性被改变,File对象在保存到数据库之前,我调用writeFileWithFileData(),并且磁盘上的数据被覆盖。这个系统按照我需要的方式工作,我进行实验。然后我创建了一个联系人。

class Contact: Object {
dynamic var objectID = NSUUID().UUIDString

dynamic var firstName = ""
dynamic var lastName = ""
...
private dynamic var avatarFile: File?

var avatar: UIImage? {
get {
guard let imageData = avatarFile?.fileData else { return nil }
return UIImage(data: imageData)
}

set {
avatarFile = File()
guard let imageData = newValue else {
avatarFile?.fileData = nil
return
}
avatarFile?.fileData = UIImagePNGRepresentation(imageData)
}
}

override static func primaryKey() -> String? {
return "objectID"
}

override static func ignoredProperties() -> [String] {
return ["image"]
}
}

问题是,当我从数据库中选择联系人并尝试获取头像时,每次访问此属性时都会发生对文件系统的访问。也就是说,属性 fileData 的操作并不像我最初想象的那样惰性。但后来我查看了avatarFile的内存地址属性,每次接收到时,地址都发生了变化。由此我可以得出结论,对象 avatarFile 不断地再次从数据库请求,并引用此属性。结果,它的所有被忽略的属性都被重置。

  1. 为什么每次访问关系对象时都会重新初始化?
  2. 分享您对我的拱门的看法

最佳答案

  1. 应该没问题。 Realm 对象是其父 Realm 对象的实时链接,而不是静态副本,因此它们的地址会定期更改。这是正常现象,并且对象不会重新分配,因此您不应在此处看到任何内存问题。据我所知, NSData 本身是惰性的,因此在您明确请求之前不会真正读取数据。

  2. 你的架构看起来不错!您是对的,通常不是将文件数据直接存储在 Realm 文件中的最佳形式,但您在使 Realm 对象像管理外部文件数据一样管理外部文件数据方面做得很好。 :)

关于ios - 为什么每次访问我的关系对象时都会重新初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33586433/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com