【发布时间】:2015-11-07 18:43:25
【问题描述】:
我使用 Realm Swift 0.95.3。在我的项目中,我正在处理一个联系人(不是联系人地址簿),其中包含有关姓名、姓氏、中间名、电子邮件……和照片的信息。
我创建了一个名为 Contact 的 Object 子类。我了解图像或任何其他二进制数据不应存储在领域中。特别是因为我的图像可能足够大〜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 会不断地再次从数据库中请求,并引用此属性。结果,它的所有被忽略的属性都被重置。
- 为什么每次访问关系对象都会重新初始化?
- 分享您对我的拱门的看法
【问题讨论】:
标签: ios database swift realm relation