【问题标题】:Core Data not returning NSMutableArray property核心数据不返回 NSMutableArray 属性
【发布时间】:2010-08-29 17:03:35
【问题描述】:

我开始觉得自己很愚蠢 - 我浏览了该网站,发现了一些与我的问题很接近但无法解决的问题(帮助 M. Zarra,读完你的书后我感觉很漂亮Core Data 很好,但现在我束手无策了!)。尽管有专家的建议,我还是选择将 NSMutableArray 作为可转换属性存储在我的核心数据实体中。数组本身填充了自定义对象,并具有所需的 encodeWithCoder: 和 initWithCoder: 方法。我在其中添加了 NSLogs 以查看它们何时触发。

现在,第一次运行,填充所有内容等,一切都很好,我确实在退出时保存了所有内容(我可以在 xml 文件中看到这些内容已被编码。)

但是,当重新启动时,检索 NSManagedObject,然后尝试访问可转换属性,我什么也没得到——尽管日志语句表明 initWithCoder: 运行成功。就好像解码是作为获取 NSManagedObject 的一部分完成的,但属性本身没有填充(我已经尝试了所有方法,包括 setReturnsObjectsAsFaults:No)。打印对象描述显示 'priceData - "(...not nil...)" 所以我真的不知道为什么它不允许访问/不返回任何内容。

我想要做的是获取 mutableArray,检查它是否包含一个元素,如果包含,则将其替换为其他元素。我从今天早上开始,以为这很简单,但 7 小时后我仍然无处可去。

有什么想法吗?对于此事,我非常感谢任何帮助/提示/建议。

[第二个问题-为什么将数据放在核心数据中的数组中显然是愚蠢的?我正在处理许多很多个别情况的长时间序列,并且将每个数据点挤出到一个实体中的选项似乎会创建一个巨大的时间序列数据点表,我认为在该表上获取性能会很快下降。我错了吗?]

代码如下:

NSManagedObjectContext *managedObjectContext = [[NSApp delegate] managedObjectContext];
//1. Retrieve the NSManagedObject with the price history from the MOC
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setIncludesSubentities:YES];
[request setIncludesPendingChanges:YES];
[request setIncludesPropertyValues:YES];
[request setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity =
[NSEntityDescription entityForName:@"stockPriceHistory" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate =
[NSPredicate predicateWithFormat:@"stock == %@", [[self selectedObjects]objectAtIndex:0]];
[request setPredicate:predicate];
NSError *error;
NSArray *array = [ managedObjectContext executeFetchRequest:request error:&error];

NSManagedObject *test = [array objectAtIndex:0];

NSLog([test description]);
NSLog(@"%@",[[test priceData] description]);

.. 给出以下日志输出(第一行是显示数组中对象的时间戳再次解码的日志):

2010-08-29 18:48:54.245 项目 X[23047:a0f] 2010-08-27 13:00:00 +0200

2010-08-29 18:48:54.246 项目 X[23047:a0f] 2010-08-26 13:00:00 +0200

2010-08-29 18:48:54.250 项目 X[23047:a0f] 2010-08-25 13:00:00 +0200

2010-08-29 18:48:54.251 项目 X[23047:a0f] 2010-08-24 13:00:00 +0200

2010-08-29 18:48:54.252 项目 X[23047:a0f] 2010-08-23 13:00:00 +0200

2010-08-29 18:48:54.253 项目 X[23047:a0f] 2010-08-20 13:00:00 +0200

2010-08-29 18:48:54.253 项目 X[23047:a0f] 2010-08-19 13:00:00 +0200

2010-08-29 18:48:54.255 项目 X[23047:a0f] 2010-08-18 13:00:00 +0200

2010-08-29 18:48:54.255 项目 X[23047:a0f] 2010-08-17 13:00:00 +0200

2010-08-29 18:48:54.256 项目 X[23047:a0f] 2010-08-16 13:00:00 +0200

2010-08-29 18:48:54.256 项目 X[23047:a0f] 2010-08-13 13:00:00 +0200

2010-08-29 18:48:54.257 项目 X[23047:a0f] 2010-08-12 13:00:00 +0200

2010-08-29 18:48:54.258 项目 X[23047:a0f](实体:stockPriceHistory;ID:0x10043d950;数据:{ 数据点数 = 0; priceData = "(...不是零..)"; 库存=“0x100445040”; })

2010-08-29 18:48:54.260 项目 X[23047:a0f] ( ) (gdb)

【问题讨论】:

    标签: performance core-data nsmutablearray


    【解决方案1】:

    你为这个类重写了 NSManagedObject 吗?如果是这样,您是否覆盖了数组的访问器?是否调用了它的 awakeFromFetch 方法? initWithCoder 调用在哪里进行?可能应该在 awakeFromFetch 中。您可以拥有一个持久属性“codedArray”和另一个非持久属性“array”。在 awakeFromFetch 中,读取 'codedArray' 属性,对其进行解码,然后设置 'array' 属性,这是其余代码将读取的内容。

    codedArray = [self valueForKey:@"codedArray"];
    // decode array...
    [self setPrimitiveValue:decodedArray forKey:@"array"]; 
    

    为什么只在 Core Data 中放置一个数组?嗯,是的,看起来确实很奇怪。如果您使用的是编码器,则可以只写入平面文件。由于您将每个对象作为自己的行发出,因此您失去了 SQL DB 的好处;在对它进行搜索之前,您必须将整个数组读入内存。

    【讨论】:

    • 感谢您的回复。我想我有点跟随。这些对象是:priceHistory:NSManagedObject,它包含可转换属性(它本身由如上所述编码的其他对象组成)。我没有对 NSMutableArray 本身进行任何编码/解码,因为我让 Core Data 这样做。所以我不确定你的方法会有什么好处?实际上,一个会有两个属性,但我认为一个会做 - 就像在我的代码中一样,它可以正常工作并正确保存内容,但由于某种原因不会将它们从 Core Data 中取出。
    • 啊,抱歉,我的 Core Data 代码是 10.4 兼容的,它没有为您完成所有编码。希望现在您不需要配对属性。您是否覆盖了 priceHistory 的 KVC 属性访问器?
    • 我确实尝试过覆盖(将标准 xcode 4 模板代码从 id 更改为 NSMutableArray),但我尝试过不覆盖任何东西 - 结果相同。
    猜你喜欢
    • 2010-11-25
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 2010-11-09
    • 2011-06-30
    相关资源
    最近更新 更多