【发布时间】:2010-01-27 01:41:40
【问题描述】:
我将双精度数组保存在 NSData* 对象中,该对象作为二进制属性保存在 Core Data (SQLite) 数据模型中。我这样做是为了在 iPhone 应用程序中存储用于绘图的采样数据。有时,当二进制对象中有超过 300 个双精度时,并非所有双精度都保存到磁盘中。当我退出并重新启动我的应用程序时,可能只有 25 个数据点保持不变或多达 300 个。
将 NSSQLitePragmasOption 与 synchronous = FULL 一起使用,这可能会有所作为。很难说,因为 bug 是间歇性的。
鉴于使用 synchronous = FULL 导致的性能问题警告,我正在寻求建议和指点。
谢谢。
[[编辑:这里是代码。]]
-addToCache 的(尚未实现的)意图:是将每个新数据添加到缓存中,但只会定期刷新(错误?)数据对象。
来自 Data.m
@动态数据集; // NSData * Data 实体的属性 - (void) addDatum:(double_t)datum { DLog(@"-[Data addDatum:%f]", datum); [self addToCache:datum]; } - (void) addToCache:(double_t)datum { 如果(缓存 == 零) { 缓存 = [NSMutableData dataWithData:[self dataSet]]; [缓存保留]; } [缓存 appendBytes:&数据长度:sizeof(double_t)]; DLog(@"-[Data addToCache:%f] ... [缓存长度] = %d; 缓存 = %p", datum, [缓存长度], 缓存); [自刷新缓存]; } -(无效)总结 { DLog(@"-[数据总结]"); [自刷新缓存]; [缓存释放]; 缓存=零; DLog(@"[self isFault] = %@", [self isFault] ?@"YES" : @"NO"); // [self isFault] 始终为 NO。 } -(无效)flushCache { DLog(@"刷新缓存到存储"); [自我设置数据集:缓存]; DLog(@"-[Data flushCache:] [[self dataSet] length] = %d", [[self dataSet] length]); } -(双*)字节 { return (double*)[[self dataSet] bytes]; } - (NSInteger) 计数 { return [[self dataSet] 长度]/sizeof(double); } -(无效)转储 { ALog(@"转储数据"); NSInteger numDataPoints = [自我计数]; 双*数据=(双*)[自字节]; ALog(@"numDataPoints = %d", numDataPoints); for (int i = 0; i【问题讨论】:
-
哇,如果这真的是框架中的错误而不是您的代码,我希望您向 Apple 提交因为这非常非常糟糕。
-
您是否考虑过为您的数据模型创建适当的实体和关系,而不是尝试将数组存储在单个属性中?
-
您是否确认数据已正确转换为二进制?我认为该错误最有可能出现在 St3fan 指出的转换代码中,我们需要查看。尝试在保存之前将其从二进制转换回双精度并进行断言检查。如果它确实在转换代码中,这将捕获错误。
-
gerry3 - 不知道你的意思。我的“实验”实体与“运行”实体具有一对多关系(用于包含),而“运行”实体与“数据”实体具有一对一关系(尽管大多数运行属性都存储在运行对象)。数据实体是来自测量的数据样本,它可以包含数万个数据点。如果有比 BLOB 更好的方式来表示它,我会全力以赴。
-
St3fan - 我为 Data 对象(它是一个 NSManagedObject)添加了一些代码。在从测量(例如温度传感器)中采样数据时,正在为每个数据点调用 -[Data addDatum:]。采样完成后,调用 -[Data wrapup]。调用者还调用 NSManagedObjectContext 上的 -save。有时 - 例如,在应用程序执行期间对多个 Run 进行采样时,或者当已经有几个已保存的 Run 时 - 新的 Run 及其数据的 NSData 属性被正确保存。但实验的第一次运行通常会被截断。
标签: iphone sqlite core-data nsdata