3

我已经搜遍了,但仍然没有找到任何非常有效的方法。问题/答案太老了,或者根本不适合我。这是我第一次尝试“我自己的”应用程序。由于这似乎是一种通行权,我正在制作一个清单应用程序。这就是我要找的东西:

我的数据存储包含 4 个属性:(name, category, isChecked, isActive随着我的扩展,肯定会有更多属性)

当我的视图控制器最初加载时,它NSFetchedResultsController有一个NSPredicate只检索属性isActive为 YES (或[NSNumber numberWithBool:YES)的记录。然后它获取这些记录并将它们显示到用户的适当单元格中。当用户单击单元格时,Data Store 会isChecked相应地更新和更改属性。到目前为止,一切都很好。

我现在需要做的是能够从列表中删除项目(1 个或多个)。具体来说,我需要它来更新数据存储属性isChecked,并且isActive只有当它的当前isChecked属性为 YES 时才更新为 NO。(我不打算从数据存储中删除记录,因为它们将用于构建数据库以供用户将来使用。)

除其他外,我使用过:

[[[self fetchedResultsController] fetchedObjects] 
   setValue:[NSNumber numberWithBool:NO] 
   forKey:@"isChecked"];

这确实有效,它会删除复选标记并相应地更新商店。问题是,我不仅向数据存储发出另一个请求以获取isActive项目,它还搜索获取的整个“活动列表”并将它们的每个isChecked属性设置为 NO。对于小列表来说,这可能不是太大的问题,但随着列表的扩展,这可能是一个问题。

另一个问题是,如果我添加:

[[[self fetchedResultsController] fetchedObjects] 
   setValue:[NSNumber numberWithBool:NO] 
   forKey:@"isActive"];

它将我的所有列表项设置为 NO(以及同一方法中的第二个数据存储请求。)

所以我的问题是:我如何才能通过列表,仅查找已检查的项目并仅更新那些isChecked属性为 YES 的记录(设置 isChecked && isActive 属性 = NO),而不是遍历整个列表?

我尝试专门为此按钮操作创建一个单独的 fetchedResultsController,它确实有效(也就是说,它没有崩溃)但调试器弹出了一个相当大的“严重应用程序错误”。我不会发布错误消息,因为它很长并且很可能与任何解决方案无关。

任何帮助将不胜感激。在此先感谢,请保持温和:-]。

编辑

我试过使用for循环,for (NSString *item in fetchedResultsController)但我得到了错误...may not respond to 'countByEnumeratingWithState:objects:count'

似乎这里需要一个循环,但同样,我找不到任何相关的东西或者它已经过时了。再次感谢您的帮助。

编辑 2

这是我为此按钮/方法运行第二个单独的 fetchRequestController 时遇到的原始错误:

An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 3 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

4

3 回答 3

2

您可以遍历 fetchedObjects 集合并更改托管对象。更改它们后,您需要重新加载列表(我猜您使用的是表格视图)。

我不知道您的类的名称是什么,但通常您可以遍历托管对象的集合并更改它们。请记住,如果您想在应用关闭时保留这些更改,则需要保存托管对象上下文。

NSArray* myCollection = [[self fetchedResultsController] fetchedObjects];
for(ActiveListData *managedObject in myCollection)
{
    if(managedObject != nil && managedObject.isChecked)
    {
        managedObject.isChecked = NO;
        managedObject.isActive = NO;
    }
}

如果要检查数据库中的所有对象,则需要在 NSFetchedResultsController 中使用一个新方法,该方法对 isChecked 进行谓词检查,然后循环并编辑结果集合。

您可能想发布您的错误代码,因为我们可以指出您做错了什么。

编辑:如果您不熟悉使用核心数据,苹果文档提供了很多信息:http: //developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/Articles/cdBasics.html

于 2013-02-15T09:07:27.500 回答
1

感谢@ggfela 的回答。他的回答过程很到位。这是我放入按钮/方法中的实际代码,希望将来能帮助其他人:

NSArray *moc = [[self fetchedResultsController] fetchedObjects];

for  (ActiveListData *item in moc) {
    if (item != nil && item.isChecked.boolValue == 1) {
        item.isChecked = [NSNumber numberWithBool:NO];
        item.isActive = [NSNumber numberWithBool:NO];
    }
}

// Call to Data Store to update the list
NSError *error;
if (![self.managedObjectContext save:&error]) {
    FATAL_CORE_DATA_ERROR(error);
    return;

解释:

将调用方法的结果内容加载fetchedResultsController到一个名为的临时变量中moc

使用for循环循环遍历moc. ActiveListData是我为我的核心数据创建的 NSManagedObject 子类,并且是从数据存储中插入分离的值/属性的合适位置。从那里开始,这很简单,我确保item不是nil并且该项目的属性是我需要的值。

笔记

Core Data 不存储布尔值 YES 和 NO,而是分别存储 1 和 0,但是当您调用或比较这些值时,您根本无法比较 的值,item.isChecked因为它作为布尔值而不是整数传回给您. 您不能简单地比较item.isChecked == YES两者,因为@propertyofisChecked是一个NSNumber. 所以,在if我放的情况下,item.isChecked.boolValue这会给我代表它的布尔值的整数,在这种情况下,我让它检查 1(是)。(对不起,如果我的解释是错误的和/或令人困惑的,但这是我理解它的方式,也是此代码工作的唯一方式。)

然后,设置这些属性的新值就像设置任何其他变量时所期望的一样。唯一“棘手”的区别是 NSManagedObject 子类将@propertyandisChecked设置isActiveNSNumber(如前所述),因此为了将正确的值发送回 Core Data,您使用类的numberWithBool方法NSNumber

万一有人对我的FATAL_CORE_DATA_ERROR(error)调用感到困惑,这只是一个在Prefix.pch文件中定义的宏,用于处理来自 managedObjectContext 的错误。您可以使用您选择的任何(或不使用)错误处理。

再次感谢@ggfela 的帮助!!如果其他人对如何应用此代码有任何其他建议,请告诉我!

于 2013-02-16T04:34:04.097 回答
0

您可以使用 NSBatchUpdateRequest 更新多条记录

例子:

https://www.bignerdranch.com/blog/new-in-core-data-and-ios-8-batch-updating/

http://code.tutsplus.com/tutorials/ios-8-core-data-and-batch-updates--cms-22164

于 2015-09-11T18:36:25.343 回答