Iphone iOS核心数据-更新多个记录

Iphone iOS核心数据-更新多个记录,iphone,xcode,sqlite,ios6,xcode4.5,Iphone,Xcode,Sqlite,Ios6,Xcode4.5,我已经搜索过了,仍然没有找到任何有效的方法。要么这个问题/答案太旧,要么根本不适合我。这是我第一次尝试“我自己的”应用程序。由于这似乎是一种通行权,我正在制作一个清单应用程序。以下是我想要的: 我的数据存储包含4个属性:name、category、isChecked、isActive(随着我的扩展,肯定还会有更多属性) 当我的视图控制器最初加载时,NSFetchedResultsController有一个NSPredicate,它只检索属性isActive为YES(或[NSNumber numb

我已经搜索过了,仍然没有找到任何有效的方法。要么这个问题/答案太旧,要么根本不适合我。这是我第一次尝试“我自己的”应用程序。由于这似乎是一种通行权,我正在制作一个清单应用程序。以下是我想要的:

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

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

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

除其他外,我使用了:

[[[self fetchedResultsController] fetchedObjects] 
   setValue:[NSNumber numberWithBool:NO] 
   forKey:@"isChecked"];
这确实有效,它会删除复选标记并相应地更新存储。问题是,我不仅要向数据存储发出另一个请求以获取
isActive
项,而且还要搜索整个“Active List”已获取并将其每个
isChecked
属性设置为否。对于小列表来说,这可能不是一个太大的问题,但随着列表的扩展,这可能是一个问题

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

[[[self fetchedResultsController] fetchedObjects] 
   setValue:[NSNumber numberWithBool:NO] 
   forKey:@"isActive"];
它将所有我的列表项设置为否(以及同一方法中的第二个数据存储请求)

因此,我的问题是:我如何浏览列表,只查找已检查的项目,并只更新那些
isChecked
属性为YES的记录(设置isChecked&&isActive attributes=NO),而不是浏览整个列表

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

如果您有任何帮助,我们将不胜感激。请提前表示感谢,并请温柔:-]

编辑

我曾尝试使用
for
循环,
for(fetchedResultsController中的NSString*项)
但我得到错误
…可能无法响应“CountByEnumerating with State:objects:count”

看起来这里需要的是某种循环,但同样,我找不到任何相关的或过时的。再次感谢您的帮助

编辑2

以下是我为该按钮/方法运行第二个单独的fetchRequestController时得到的原始错误:


调用-controllerDidChangeContent时从NSFetchedResultsController的委托捕获异常:。无效更新:节0中的行数无效。更新(4)后现有节中包含的行数必须等于更新(4)前该节中包含的行数,加上或减去从该节插入或删除的行数(插入0行,删除3行),加上或减去移入或移出该节的行数(移入0行,移出0行)。使用userInfo(null)

您只需在FetchedObject集合上循环并更改托管对象。更改后,您需要重新加载列表(我猜您使用的是tableview)

我不知道您的类的名称,但一般来说,您只需在托管对象集合上循环并更改它们。请记住,如果要在应用程序关闭时保留这些更改,则需要保存托管对象上下文

NSArray* myCollection = [[self fetchedResultsController] fetchedObjects];
for(ActiveListData *managedObject in myCollection)
{
    if(managedObject != nil && managedObject.isChecked)
    {
        managedObject.isChecked = NO;
        managedObject.isActive = NO;
    }
}
如果要对数据库中的所有对象执行检查,则需要在NSFetchedResultsController中使用一个新方法,该方法在isChecked上具有谓词检查,然后循环并编辑结果集合

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


编辑:如果你不熟悉核心数据的使用,苹果的文档提供了很多信息:

感谢@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子类,是插入数据存储中分离的值/属性的合适位置。从这里开始,非常简单,我确保
不是
nil
a然后确定项目的属性是我需要的值

注意

核心数据不存储布尔值YES和NO,而是分别存储1和0,但是当您调用或比较这些值时,您根本无法比较
项的值。isChecked
,因为它是作为布尔值而不是整数传递给您的。您也不能简单地比较
项。isChecked==YES
,因为e>
isChecked的@property
是一个
NSNumber
。因此,在
if
的情况下,我放入
项.isChecked.boolValue
,因为这将给出它的bool值的表示整数,在这种情况下,我有I