【问题标题】:Truncated Core Data NSData objects截断的核心数据 NSData 对象
【发布时间】: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


【解决方案1】:

我试图让我的核心数据实体可以具有 NSMutableData 属性的行为。为此,我的 NSManagedObject(称为 Data)有一个 NSData 属性一个 NSMutableData ivar。我的应用从传感器获取样本数据并将每个数据点附加到数据集 - 这就是我需要这种设计的原因。

在每个新数据点上附加到 NSMutableData,然后将 NSData 属性设置为 NSMutableData。

我怀疑因为 NSData 指针没有改变(尽管它的内容是),Core Data 并没有意识到改变的数量。在 NSManagedObjectContext 上调用 -hasChanged 表明发生了更改,调用 -updatedObjects 甚至将 Data 对象列为已更改。但正在写入的实际数据似乎已被截断(有时)。

为了解决这个问题,我稍微改变了一些东西。新数据点仍然附加到 NSMutableData NSData 属性仅在采样完成时设置。这意味着崩溃有可能导致数据被截断 - 但在大多数情况下,这种解决方法似乎已经解决了问题。

警告购买者:错误总是间歇性的,所以它可能仍然存在 - 但更难表现出来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多