Dee*_*pak 8 xcode core-data ios
如何获取核心数据存储中存在的数据的总内存大小(以字节为单位).如何获取特定数据行的内存大小.
在iOS 7及更高版本上,由于SQLite日志文件,旧的答案不再适用于SQLite支持的持久存储.对于每个持久性存储文件,您需要获取SQLite文件本身的大小(例如Foo.sqlite)和日志文件的大小(例如Foo.sqlite-wal和Foo.sqlite-shm),并添加大小以获得总数.这非常重要,因为很可能大多数数据实际上都在日志文件中.您可以使用它NSFileManager来获取每个文件的此信息.
如果您在模型中使用二进制属性并且为这些属性启用了"允许外部存储",则会变得更加复杂.在这种情况下,您需要找到所有外部存储文件并添加其大小.它们的位置没有记录,但应该位于找到SQLite文件的目录的子目录中.对于名为的SQLite文件,Foo.sqlite查找名为的目录.Foo_SUPPORT/_EXTERNAL_DATA,外部二进制文件将在那里.由于没有记录,因此可能会在没有警告的情况下进行更改.
更好的方法 - 如果不是太晚 - 就是将持久存储放在它自己的子目录中.不要将其放在文档目录中,而是在文档中创建一个新目录并将SQLite文件放在那里.也就是说,创建一个名为like的目录data并放入Foo.sqlite其中.要添加大小,只需递归扫描每个文件data并添加大小.然后你会抓住所有东西,即使日记或外部二进制文件或iOS未来版本中的任何变化.做扫描的一个好方法是用NSFileManager的enumeratorAtPath:或enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:方法.
查找特定数据行的内存大小是一个非常不同的问题,并且没有通用的解决方案.任何对象实例的开销,加上您的属性,以及任何内部未记录的对象都NSManagedObject可能创建(包括实例变量和动态分配的内存).它甚至不是固定值,因为可以动态分配和释放数据.只添加属性的大小很容易 - 只需运行它们并加上每个的大小(字符串长度,数据长度等),但这不是完整的图片.
使用 Swift 5,我想出了这个答案。它不仅获取存储和文件的大小,还使用 Apple 的ByteCountFormatter格式化数据大小。
public func getSqliteStoreSize(forPersistentContainerUrl storeUrl: URL) -> String {
do {
let size = try Data(contentsOf: storeUrl)
if size.count < 1 {
print("Size could not be determined.")
return ""
}
let bcf = ByteCountFormatter()
bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only
bcf.countStyle = .file
let string = bcf.string(fromByteCount: Int64(size.count))
print(string)
return string
} catch {
print("Failed to get size of store: \(error)")
return ""
}
}
Run Code Online (Sandbox Code Playgroud)
使用方法非常简单:
// Get Core Data storage size:
guard let storeUrl = self.managedObjectContext!.persistentStoreCoordinator!.persistentStores.first?.url else {
print("There is no store url")
return
}
print("The size of the store is: \(self.getSqliteStoreSize(forPersistentContainerUrl: storeUrl))")
Run Code Online (Sandbox Code Playgroud)
这里的一个小细节是确保您检查您的moc和persistentStoreCoordinator确实具有价值 - 就我而言,我知道它们具有价值,因为我初始化它们的方式。
关于上面考虑到wal和shm文件的答案,您可以通过将字符串附加到 URL 来检查这些文件:
let newFileName = storeUrl.absoluteString.appending("\("-wal")")
let newFileName2 = storeUrl.absoluteString.appending("\("-shm")")
print("The size of the wal is: \(self.getSqliteStoreSize(forPersistentContainerUrl: URL(string: newFileName)!))")
print("The size of the shm is: \(self.getSqliteStoreSize(forPersistentContainerUrl: URL(string: newFileName2)!))")
Run Code Online (Sandbox Code Playgroud)
- (void)reportFileSizeOfPersistentStores
{
NSArray *allStores = self.persistentStoreCoordinator.persistentStores;
NSFileManager *fileManager = [NSFileManager defaultManager];
for (NSPersistentStore *store in allStores)
{
NSString *filePath = store.URL.path;
NSDictionary *attributes = [fileManager attributesOfItemAtPath:filePath
error:nil];
NSString *fileSize = attributes[NSFileSize];
NSLog(@"FileSize:%@", fileSize);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1790 次 |
| 最近记录: |