我从这样的类实例创建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. 6 秒,文件大小为 ~70MB。很慢!我试图将db
实例分成 2 个不同的部分 (~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
鉴于您需要从应用程序会话开始就内存中的所有数据,因此您将不得不使用除NSKeyedArchiver
以外的解决方案。 NSKA 旨在存档复杂的对象图,因此经过优化以解决不同的问题。
在您的情况下,我建议一个构建阶段,将静态数据写入无需解析即可映射到内存中的文件格式。 然后,在运行时,映射文件并传递将其转换为 Foundation 类型中的最小封装。
对于字符串,类似字符串表的解决方案将足够好用。 也许约会可能有点棘手。 我会测试一下基于时间间隔的创建方法是否很快。 如果是,那么您可以将日期存储为映射文件中的数组(不是 NSArrays,而是 NSTimeIntervals 的平面 C 数组)并执行修正传递。
当然,您也可以根据应用中的访问模式跳过对某些数据子集的修正。 如果您的用户并没有真正一次查看所有日期,则无需在加载时修复它们,但可以按需创建它们。