我已经洗过,但仍然没有发现任何有效的东西。问题/答案太旧或者根本不适用于我。这是我第一次尝试“我自己的”应用程序。由于它似乎是通行权,我正在制作一个清单应用程序。这就是我要找的东西:
我的数据存储包含4个属性:name, category, isChecked, isActive
(扩展后肯定会更多)
当我的View Controller最初加载时,NSFetchedResultsController
有一个NSPredicate
,只检索属性isActive
为YES(或[NSNumber numberWithBool:YES
)的记录。然后,它会获取这些记录并将其显示在用户的相应单元格中。当用户单击某个单元格时,数据存储会相应地更新并更改isChecked
属性。到目前为止一切都很好。
我现在需要做的是能够从列表中删除项目(1个或多个)。具体来说,我需要它将数据存储属性isChecked
和isActive
更新为NO,前提是它的当前isChecked
属性为YES。 (我不打算从数据存储中删除记录,因为它们将用于构建数据库以供将来用户使用。)
我已经使用过,其中包括:
[[[self fetchedResultsController] fetchedObjects]
setValue:[NSNumber numberWithBool:NO]
forKey:@"isChecked"];
这确实有效,它会删除复选标记并相应地更新商店。问题是,我不仅向isActive
项的数据存储发出另一个请求,还搜索已获取的整个“活动列表”,并将每个isChecked
属性设置为NO。对于小型列表而言,这可能不是一个大问题,但随着列表的扩展,这可能是一个问题。
另一个问题是,如果我添加:
[[[self fetchedResultsController] fetchedObjects]
setValue:[NSNumber numberWithBool:NO]
forKey:@"isActive"];
它将我的所有列表项设置为NO(以及同一方法中的第二个数据存储请求。)
所以我的问题是:如何查看列表,只查找已检查的项目并仅更新那些记录(设置isChecked&& isActive attributes = NO),其isChecked
属性为是,而不是整个清单?
我已经尝试专门为这个按钮操作创建一个单独的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)
答案 0 :(得分: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进行谓词检查,然后循环并编辑结果集合。
您可能希望发布错误代码,因为我们可以指出您做错了什么。
编辑:如果您不熟悉使用Core Data,那么Apple文档会提供大量信息:http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/Articles/cdBasics.html
答案 1 :(得分: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
并且项目的属性是我需要的值。
注意
核心数据不会将bool值存储为YES和NO,而是分别存储1和0,但是当您调用或比较值时,您无法比较item.isChecked
的值,因为它被传递回你作为一个bool而不是一个整数。您不能简单地比较item.isChecked == YES
,因为@property
的{{1}}是isChecked
。所以,在NSNumber
我放if
的情况下,因为这将给出我的bool值的代表整数,在这种情况下,我检查它是1(是)。 (对不起,如果我的解释错误和/或令人困惑,但这是我理解它的方式,也是此代码工作的唯一方式。)
然后,设置这些属性的新值就像设置任何其他变量时所期望的那样。与此唯一“棘手”的区别是NSManagedObject子类将item.isChecked.boolValue
和@property
的{{1}}设置为isChecked
(如前所述),以便发送正确的值返回到核心数据,您使用isActive
类的方法NSNumber
。
如果有人对我的numberWithBool
调用感到困惑,这只是一个在NSNumber
文件中定义的宏,用于处理来自managedObjectContext的错误。您可以使用您选择的任何(或无)错误处理。
再次感谢@ggfela的帮助!!如果其他人对如何应用此代码有任何其他建议,请告诉我们!
答案 2 :(得分:0)