【问题标题】:Is it a good idea for saving many images (less than 2MB per image) in Realm?在 Realm 中保存许多图像(每张图像小于 2MB)是一个好主意吗?
【发布时间】:2018-01-05 21:34:44
【问题描述】:

最近,我正在考虑将我的应用数据从 Core Data 迁移到 Realm。

但我担心的是Realm中没有一个属性叫做:Allows External Storage。我制作的应用程序有很多图像需要保存。所以,我认为在 Realm 中将这些图像保存为 Data 类型并不是一个好主意,尽管所有这些图像都小于 2MB(每张图像)。

所以,我的问题是:

  1. 将这些图像保存到 Realm 中的Data 是个好主意吗? (每张图片不到 2MB,但有很多图片) 不是一个好主意。
  2. 如果这不是一个好主意。如何将图像保存到本地文件系统中,而不仅仅是使用String 类型来映射它们。我想使用新的类型(例如 RealmImage)

像这样:

class Person: Object {
    var name: String
    var avatar: ObjectWithImage
}
class ObjectWithImage : RealmObject {
    var imageUrl: String
}

不是这个:

class Person: Object {
    var imageUrl: String
}

所以,我不想仅将图像文件路径保存为 String 类型。我想要做的是创建一个新类型(例如ObjectWithImage 或类似的),它将包含图像的文件路径。原因是我也在使用 CloudKit。所以我必须用 CloudKit 类型映射所有 Realm 类型。如果是String类型,会和原来的String类型冲突。

问题是CKAsset。我想要的是它可以支持CKAssetObjectWithImage可以映射到CKAsset

以下代码是其他类型的示例代码,我想在下面的代码中支持CKAsset

public protocol CKRecordRecoverable {
    associatedtype O: Object
}

extension CKRecordRecoverable {//Mapping from CKRecord
    func parseFromRecord(record: CKRecord) -> O? {
        let o = O()
        var recordValue: Any?
        for prop in o.objectSchema.properties {
            switch prop.type {
            case .int:
                recordValue = record.value(forKey: prop.name) as? Int
            case .string:
                recordValue = record.value(forKey: prop.name) as? String
            case .bool:
                recordValue = record.value(forKey: prop.name) as? Bool
            case .date:
                recordValue = record.value(forKey: prop.name) as? Date
            case .float:
                recordValue = record.value(forKey: prop.name) as? Float
            case .double:
                recordValue = record.value(forKey: prop.name) as? Double
            case .data:
                recordValue = record.value(forKey: prop.name) as? Data
            default:
                print("Other types will be supported in the future.")
            }
            o.setValue(recordValue, forKey: prop.name)
        }
        return o
    }
}

public var record: CKRecord {
    let r = CKRecord(recordType: Self.recordType, recordID: recordID)
    let properties = objectSchema.properties
    for prop in properties {//Mapping to CloudKit type
        r[prop.name] = self[prop.name] as? CKRecordValue
    }
    return r
}

那么,有什么想法吗?

------------编辑-------------

所以根据 cmets,我认为第二个选项是一个好方法:将图像保存到本地文件存储中。

谁能帮我想想如何用CKRecord映射它

parseFromRecordrecord 方法中。定义一个新的类型来处理图像并将图像保存到本地文件存储中。

我现在对此一无所知。非常感谢。

我从这个链接得到了一个原因:Why is it recommended practice to store images on disk rather than in a Realm

但还是想知道怎么弄……

【问题讨论】:

  • AFAIK 不建议在 Realm 中存储图像,因为 Realm 会创建内存中的实例。这意味着如果您在 Realm 中存储大量图像,您的应用程序的内存使用量可能会变大。此外,如果您的 Realm 文件较大,则查询可能需要更长的时间才能运行。另一种方法是将图像本身存储在 Realm 之外的文件系统中,并且仅将本地文件路径存储在 Realm 中。
  • 我也会推荐@DávidPásztor 的建议。
  • @Dávid Pásztor 是的。我现在同意。那么您对上述代码中的CKRecordRecoverablerecord 方法有什么建议吗?给定一个新类型并用 CKRecord 映射它。

标签: ios swift core-data realm


【解决方案1】:

当您看到 Allows External Storage 的 CoreData 复选框时,“外部”一词并不意味着它存储在云端或设备外的其他地方。它只是意味着它可能存储在持久存储之外的文件中。

换句话说,即使您选中了Allows External Storage,您的照片仍会占用用户设备上的空间。

【讨论】:

  • 嗨,creeperspeak,我知道这不是为了保存在云端,而是保存在外部存储中。这是一个本地文件系统。可能我的描述不清楚。我会说清楚的。我的意思是将图像保存在文件系统中,而不是 Realm 本身。
  • @YuanFu 好的 - 我明白了。我以为您担心占用设备上的空间。在这种情况下,为令人困惑的答案道歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 2015-01-04
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
相关资源
最近更新 更多