对于符合NSCoding的某些对象,我有一个非常基本的缓存系统。方法获取对象,提取键和搜索参数的一些信息,创建或更新NSManagedObject,并将其保存到持久存储:
+ (void)updateQuestion:(StacManQuestion *)question site:(StacManSite *)site
{
// 1. Look up with a basic predicate.
SECachedQuestion *cachedQuestion = [SECachedQuestion
findFirstWithQuestionId:question.questionId site:site];
// 2. Create if missing.
if (!cachedQuestion) {
cachedQuestion = [SECachedQuestion MR_createEntity];
cachedQuestion.questionId = question.questionId;
cachedQuestion.site = site.apiSiteParameter;
}
// 3. Update properties.
cachedQuestion.isFavorite = question.favorited;
cachedQuestion.lastAccessTime = [NSDate date];
cachedQuestion.question = question;
// 4. Save
[[NSManagedObjectContext MR_contextForCurrentThread]
MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
/* ... */
}];
}
此代码第一次运行时,它完美运行。该对象将保存到缓存中,并立即可用于下一次运行。然而,在此之后,为cachedQuestion.question
分配新值不会做任何事情。
我添加了一些断点并找到了以下内容:
问题分配不会更新changedValues
:
(lldb) po [cachedQuestion changedValues] { lastAccessTime = "2014-07-16 17:16:45 +0000"; }
question
和cachedQuestion.question
从不同的地址开始,然后以相同的方式结束,因此肯定会发生分配。
如果我在设置cachedQuestion.question = nil
的作业之前放了一步,我会得到以下内容,但问题记录在重新分配时会再次消失。
(lldb) po [cachedQuestion changedValues] { lastAccessTime = "2014-07-16 17:16:45 +0000"; question = "<null>"; }
这是另一个超级的事情。我继续进行测试,我只为{+ 1}}设置应用程序的几个版本。这适用于单次运行中的后续查找,但每次应用程序启动时,第一次读取cachedQuestion.question都会返回到原始值!我可以确认是否已开始创建新的缓存问题和 lastAccessTime没有问题更新。只是这一个字段被及时冻结。 这是因为数据验证。 cachedQuestion.question = nil
让它显示更改后的值,但保存失败,因为它不是可选的。
更新
现在我正在做一个悲伤的悲伤黑客,任何时候有变化我删除旧记录并插入一个新记录。它运作得很好,但我更想知道出了什么问题。
答案 0 :(得分:0)
您没有将更改写入正确的上下文。首先,停止使用contextForCurrentThread。它已被弃用,并且会导致您在100次中出现1次崩溃,这太多了。您还冒着崩溃的风险,因为此方法可以并且将返回不是默认上下文的上下文。在各种情况下进行托管对象分配也会崩溃,这是有充分理由的。
相反,您应该明确创建上下文,将更改写入其中,然后在方法结束时保存它。这可能会解决你所看到的大部分问题。
答案 1 :(得分:0)
我不得不多次阅读这篇文章...... 我认为这里的问题是你没有正确使用关系。 应将NSManagedObjects设置为实体。
它不应该是可转换的,而是与实体的关系。
从上下文中,您可以获取MutableArray中第一个实体中的第一个所有对象,然后通过在选择一个对象时调用此关系,在对象的新MutableArray中获取所有相关对象:
self.newArray = [[self.oldObject.relationshipName allObjects] mutableCopy];
然后,您将只获取与所选对象相关的内容,而不是相关实体中的所有对象。
这意味着不应该有问题属性,而是与实体问题的关系。