NSManaged Object Context 无法删除对象

Posted

技术标签:

【中文标题】NSManaged Object Context 无法删除对象【英文标题】:NSManaged Object Context can't delete object 【发布时间】:2013-03-22 17:20:51 【问题描述】:

我正在为我的 ios 应用程序使用 Core Data,在我的 fetch 请求中,我通过某个属性执行 fetch GROUP。因为我必须 GROUP BY,所以结果类型是 NSDictionary 而不是托管对象。

表格视图工作正常,我面临的唯一问题是删除行。它不会删除行,上下文也不会删除对象。

我做了一些挖掘,发现如果我的结果类型是托管对象,那么上下文可以删除对象并且表视图行被删除,但是 GROUP BY 功能丢失了,因为它只在结果类型为一个 NSDictionary 对象。

任何帮助将不胜感激。

这就是 FETCH REQUEST 方法(已编辑)

NSError * anyError = nil;

AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Merchant" inManagedObjectContext:context];
[request setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"premiumActName" ascending:YES];

NSArray *descriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

[request setSortDescriptors:descriptors];

NSPropertyDescription *accountDesc = [[entity propertiesByName] objectForKey:@"premiumActName"];

NSExpressionDescription* objectIdDesc = [NSExpressionDescription new];
objectIdDesc.name = @"objectID";
objectIdDesc.expression = [NSExpression expressionForEvaluatedObject];
objectIdDesc.expressionResultType = NSObjectIDAttributeType;

NSArray *propertiesToFetch= @[accountDesc, objectIdDesc];

[request setPropertiesToFetch:propertiesToFetch];
[request setPropertiesToGroupBy:[NSArray arrayWithObjects:accountDesc, nil]];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];

NSArray *distinctResults = [context executeFetchRequest:request error:&anyError];

NSLog(@"function=%s", __PRETTY_FUNCTION__);

NSLog(@" result =%@", distinctResults);

if(!_fetchedResultsController)

    _fetchedResultsController = nil;


_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];

if(![_fetchedResultsController performFetch:&anyError])

    NSLog(@" Error =%@", anyError);


if (![context save:&anyError])

    // Handle the error.

这就是表视图删除行方法(EDITED)

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    AppDelegate *applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

NSDictionary * dictionary = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSManagedObjectID * iod = [dictionary objectForKey:@"objectID"];

NSManagedObject * object = [context objectWithID:iod];

if (editingStyle == UITableViewCellEditingStyleDelete)
             
    [context deleteObject:object];

    // Commit the change.
    NSError *error = nil;

    if (![context save:&error])
    
        NSLog(@"Couldn't save: %@", error);
    


    [self.membersTblView reloadData];
 

这也不会删除对象和表格视图行!

【问题讨论】:

【参考方案1】:

你的情况

NSManagedObject * object = [self.fetchedResultsController objectAtIndexPath:indexPath];

实际上返回的不是托管对象而是字典,因此[context deleteObject:object] 不起作用。

以下方法可行:

"objectID" 添加到propertiesToFetch

删除对象:

NSDictionary *dict = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSManagedObjectID *oid = [dict objectForKey:@"objectId"];
NSManagedObject *object = [context objectWithID:oid];
[context deleteObject:object];
[context save:&error];

由于具有字典结果类型的获取结果控制器不会自动更新,因此您还必须调用:

[self.fetchedResultsController performFetch:&error];
[self.membersTblView reloadData];

再次。

【讨论】:

@AngadManchanda:你能验证oid 是一个托管对象ID,而object 是一个托管对象吗? 它实际上在幕后工作,当我按下删除时,它什么也不做,当我查看会出现或查看加载(重新启动应用程序)时,我看到该行已被删除.所以我错过了一些代码吗? @AngadManchanda:您还必须再次调用 performFetch,请参阅我的更新答案。 你是对的。那成功了。看来我必须详细阅读苹果文档。

以上是关于NSManaged Object Context 无法删除对象的主要内容,如果未能解决你的问题,请参考以下文章

PHPhotos 和核心数据。 PHObject 使用啥 NSManaged 对象类型?

对于 @NSManaged 变量,fileprivate 是不是足够?

@NSManaged 有啥作用?

存储的属性需要一个初始值或者应该是@NSManaged

NSManaged 对象 initWithCoder 错误

在 Xcode 8.2 beta 中创建 NSManaged 子类时出错