2013-02-15 26 views
2

我已经搜索过,仍然没有发现任何相当有效的东西。问题/答案太旧了,或者它根本不适合我。这是我第一次尝试“我自己的”应用程序。因为它似乎是通过的权利,我正在制作一个清单应用程序。下面是我在寻找:iOS核心数据 - 更新多个记录

我的数据存储库包含4个属性:name, category, isChecked, isActive(更多必将随之而来,因为我扩大)

当我的视图控制器最初的负荷,NSFetchedResultsControllerNSPredicate,仅检索记录其属性isActive为YES(或[NSNumber numberWithBool:YES)。然后它将这些记录显示给用户的适当单元格。当用户单击一个单元时,Data Store会相应地更新并更改isChecked属性。一切都很好,至此。

我现在需要做的是能够从列表中删除项目(1或更多)。具体而言,我需要它将数据存储属性isCheckedisActive更新为NO,只有当它的当前isChecked属性为YES时。 (我并不想从数据存储删除记录,因为它们将被用来建立,为用户未来使用的数据库。)

我用过,除其他事项外:

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

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

另一个问题是,如果我添加:(以及同样的方法中的第二数据存储请求)

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

它集我名单中所有项目没有

所以我问题是:如何才能通过列表,找到仅检查的项目并只更新那些记录(同时设置isChecked & & isActive attributes = NO),其isChecked属性为YES,而不是遍历整个列表?我试过创建一个单独的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)

回答

2

你可以在fetchedObjects收集循环,更改托管对象。改变它们之后,你需要重新加载你的列表(我猜你使用了tableview)。

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

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

+0

我想这一点,使用'ActiveListData'这是我NSManaged子类的名称,但得到了错误'异常在核心数据更改处理期间被捕获。这通常是NSManagedObjectContextObjecsDidChangeNotification观察者中的一个错误。 userInfo(null)在索引0处的索引3处没有对象。查看我的编辑上面的原始错误,我为此创建了一个单独的“fetchRequestController”。 – 2013-02-15 09:19:30

+0

是啊,我看着苹果开发文档和有信息的TON,但一大堆的理论都要经过找一个实际的例子(如果有曾经是一个例子)。至少在这里,我可以把我需要的东西放到一个环境中,并得到一个相对直接的答案。我读了开发文档尽我所能,但它并不总是最容易的地方的答案 – 2013-02-15 09:25:47

+0

是什么fetchedObjects返回?它是一个NSArray? – ggfela 2013-02-15 09:44:19

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是我为Core Data创建的NSManagedObject子类,它是从数据存储中插入分隔值/属性的适当位置。从那里,这很简单,我确保item不是nil,并且该项目的属性是我需要的值。

注意

核心数据不存储布尔值YES和NO,而是1和0,但是当你打电话或者比较值,你根本就不是因为它是比较item.isChecked值作为一个bool而不是一个整数传回给你。你不能简单地比较item.isChecked == YES,因为@propertyisCheckedNSNumber。因此,在if的情况下,我放入item.isChecked.boolValue,因为这会给出它的bool值的表示整数,在这种情况下,我会检查它是否为1(是)。 (很抱歉,如果我的解释是错误的和/或混乱,但是这是我的理解它,是这个代码工作的唯一方式。)

然后,设置这些属性的新值,就像设置任何时候,你会期望其他变量。这个唯一的“刁钻”的区别是,NSManagedObject子类设置isCheckedisActive@propertyNSNumber(如前所述),所以为了正确的价值观发送回核心数据使用NSNumber类的方法numberWithBool

以防万一有人被我的FATAL_CORE_DATA_ERROR(error)呼叫混淆这很简单,就是在该Prefix.pch文件中定义为从managedObjectContext处理我的错误的宏。您可以使用您选择的任何(或全部)错误处理。

再次感谢@ggfela您的帮助!如果其他人有关于如何应用此代码的其他建议,请让我知道!

+0

干得好,我完全忘了CoreData使用NSNumbers代替布尔值。 – ggfela 2013-02-17 08:57:09