ios - 快速 NSData 解档

标签 ios objective-c nsdata

我从这样的类实例创建 NSData:

NSData* data = [NSKeyedArchiver archivedDataWithRootObject:db];
[data writeToFile:@"/Users/.../db.data" atomically:true];

然后我需要加载这个实例:

NSURL* dbUrl = [[NSBundle mainBundle]URLForResource:@"db" withExtension:@"data"];
NSData* dbData = [NSData dataWithContentsOfURL:dbUrl];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    self.db = [NSKeyedUnarchiver unarchiveObjectWithData:dbData];
});

此加载持续 cca。约 70MB 文件大小需要 6 秒。速度很慢!我试图将 db 实例分成两个不同的部分(~35MB)并像这样加载它们:

self.db = [[Database alloc]init];
NSURL* dbUrl1 = [[NSBundle mainBundle]URLForResource:@"db1" withExtension:@"data"];
NSData* dbData1 = [NSData dataWithContentsOfURL:dbUrl1];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    self.db.nodes = [NSKeyedUnarchiver unarchiveObjectWithData:dbData1];
});
NSURL* dbUrl2 = [[NSBundle mainBundle]URLForResource:@"db2" withExtension:@"data"];
NSData* dbData2 = [NSData dataWithContentsOfURL:dbUrl2];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    self.db.trips = [NSKeyedUnarchiver unarchiveObjectWithData:dbData2];
});

以这种方式加载持续 cca。 3 秒(快 2 倍)。您知道其他更快加载的方法吗?

编辑 1:

我不确定它是否有帮助,但存档对象有两个 NSMutableArray 实例。第一个包含很多 Node 对象:

@interface DatabaseNode : NSObject <NSCoding>

@property (assign, nonatomic) NSInteger index;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) double lat;
@property (assign, nonatomic) double lon;

@end

第二个包含很多Trip对象:

@interface DatabaseTrip : NSObject <NSCoding>

@property (assign, nonatomic) NSInteger index;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) NSInteger service;
@property (strong, nonatomic) NSMutableArray* departureTimes; //Contains NSDate

@end

最佳答案

鉴于您需要应用程序 session 开始时内存中的所有数据,您将不得不采用 NSKeyedArchiver 以外的解决方案。 NSKA 旨在归档复杂的对象图,因此经过优化以解决不同的问题。

在您的情况下,我建议构建阶段将静态数据写入无需解析即可映射到内存的文件格式。然后,在运行时映射文件并进行传递,将其转换为 Foundation 类型中的最小封装。

对于字符串,像解决方案这样的字符串表就足够了。日期可能有点棘手,也许。我会测试一下基于时间间隔的创建方法是否很快。如果是,那么您可以将日期作为数组(不是 NSArrays,而是 NSTimeIntervals 的平面 C 数组)存储在映射文件中并进行修复。

当然,您也可以根据应用中的访问模式跳过某些数据子集的修复。如果您的用户并不真正一次查看所有日期,则无需在加载时修复它们,但可以按需创建它们。

关于ios - 快速 NSData 解档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49731882/

相关文章:

ios - NSDictionary allKeys,然后使用选择器与 keysSortedByValueUsingSelector 进行排序

javascript - 将 socket.io 加载到 JavaScriptCore for iOS

ios - 如何在 iOS 中隐藏带动画的标签栏?

ios - iOS7 和 iOS8 返回的 UIScreen 边界不同

objective-c - 以编程方式检查监视器是否已关闭

Objective-c - NSData initWithContentsOfFile 与 dataWithContentsOfFile

ios - 按钮覆盖显示在按钮文本、SwiftUI 上

ios - 在 Objective C 中解密 AES-256-CBC

ios - 将 pdf 图像转换为 NSData for Parse.com

ios - 如何在swift 3中压缩数据?