NSMutableArray 删除一个条目后丢失所有条目

Posted

技术标签:

【中文标题】NSMutableArray 删除一个条目后丢失所有条目【英文标题】:NSMutableArray loses all entries after deleting one entry 【发布时间】:2013-12-10 13:28:28 【问题描述】:

我正在尝试让核心数据正常工作的测试应用程序,但目前我没有进一步了解,我希望有人可以帮助我。

我正在创建一个应用程序来存储客户及其项目。我使用带有 Big Nerd Ranch 应用程序的核心数据作为示例。这个应用程序使用核心数据。

我想要完成的是您可以从客户端删除项目。只有当我从具有多个项目的客户中删除一个项目时,我的程序才会出错。

在底部的日志文件中可以看到,删除后,我的方法

-(NSArray *)relatedProjects:(Client *)client

不再包含任何项目。虽然在

-(void)removeProject:(Project *)project

日志显示 2 个条目。

我正在使用数据存储:

-(NSArray *)relatedProjects:(Client *)client; 
    NSFetchRequest *request = [[NSFetchRequest alloc]init];

    NSEntityDescription *e = [[model entitiesByName] objectForKey:@"Project"];

    [request setEntity:e];

    // Check if client is related to Project
    [request setPredicate: [NSPredicate predicateWithFormat:@"clients = %@", client.objectID]];

    NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"project"
                                                         ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:sd]];

    NSError *error;
    NSArray *result = [context executeFetchRequest:request error:&error];

    if (!result) 
        [NSException raise:@"Fetch failed"
                    format:@"Reason: %@", [error localizedDescription]];
    

    relatedProjects = [[NSMutableArray alloc] initWithArray:result];

    for (NSString *p in relatedProjects) 
        NSLog(@"RELATEDPROJECTS %@", p );
    

    if ([relatedProjects count] == 0) 
        NSLog(@"relatedProjects is empty");
    


    return relatedProjects;
     

-

-(void)removeProject:(Project *)project 
    // remove from NSManagedObjectContext
    [context deleteObject:project];

    // remove from allProjects array
    [allProjects removeObjectIdenticalTo:project];

    NSLog(@"relatedprojects in remove %@", relatedProjects);

    // remove from relatedProjects array
    [relatedProjects removeObjectIdenticalTo:project];

    NSLog(@"relatedprojects in AFTER remove %@", relatedProjects);

    NSLog(@"removed project %@", [project project]);


还有我的 ViewController

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
    if (editingStyle == UITableViewCellEditingStyleDelete) 
        BITDataStore *ds = [BITDataStore sharedStore];
        NSArray *selectedProjects = [ds relatedProjects:client];

       /* for (NSString *p in selectedProjects) 
            NSLog(@"selectedProjects %@", p );
                   NSLog(@"IndexPath row %d", [indexPath row]);
        
        */

        Project *pr = [selectedProjects objectAtIndex:[indexPath row]];
        NSLog(@" te verwijderen project is %@ voor client %@", [pr project], [client name]);

        [ds removeProject:pr];

        // Delete the row from the data source
       [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];   // lijkt dezelfde werking te hebben: [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

       
    else if (editingStyle == UITableViewCellEditingStyleInsert) 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
          

我的日志

2013-12-10 14:11:49.863[37414:70b] relatedprojects in remove (
    "<NSManagedObject: 0x8c83880> (entity: Project; id: 0x8c83260 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p4> ; data: \n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = 123;\n    tasksProjects = \"<relationship fault: 0x8e71750 'tasksProjects'>\";\n)",
    "<NSManagedObject: 0x8c83ac0> (entity: Project; id: 0x8c83270 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p1> ; data: \n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = ABC;\n    tasksProjects = \"<relationship fault: 0x8c894f0 'tasksProjects'>\";\n)",
    "<NSManagedObject: 0x8c83b20> (entity: Project; id: 0x8c83280 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p2> ; data: \n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = XYZ;\n    tasksProjects = \"<relationship fault: 0x8d68f90 'tasksProjects'>\";\n)"
)
2013-12-10 14:11:49.863[37414:70b] relatedprojects in AFTER remove (
    "<NSManagedObject: 0x8c83880> (entity: Project; id: 0x8c83260 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p4> ; data: \n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = 123;\n    tasksProjects = \"<relationship fault: 0x8e71750 'tasksProjects'>\";\n)",
    "<NSManagedObject: 0x8c83b20> (entity: Project; id: 0x8c83280 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p2> ; data: \n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = XYZ;\n    tasksProjects = \"<relationship fault: 0x8d68f90 'tasksProjects'>\";\n)"
)
2013-12-10 14:11:49.864[37414:70b] removed project ABC
2013-12-10 14:11:49.865[37414:70b] related projects is empty
2013-12-10 14:11:49.866[37414:70b] **** client in numberOfRowsInSection is CLIENTX
2013-12-10 14:11:49.866[37414:70b] related projects is empty

我的模型按要求:

我的删除规则:

【问题讨论】:

你能发布核心数据模型图吗? 您是否使用了某种类型的约束,可能会导致您的数组返回 null 不,我没有使用任何约束。谢谢 删除规则呢? 删除规则在 -(void)removeProject:(Project *)project 还是你的意思是别的? 【参考方案1】:

我不确定我是否理解您的目标,但是...如果我删除一个客户,我想删除他的所有项目。所以projects 的级联规则是可以的。相反,如果我删除一个项目,则不应删除客户端。所以,为clients 无效应该更好。

这对你有用吗?请也参考我之前的回答,因为对这个论点有深入的解释。

Setting up a parent-child relationship in Core Data

【讨论】:

是的,就是这样!这几天我一直在寻找这个。我忙着看代码,忘记了删除规则。非常感谢!

以上是关于NSMutableArray 删除一个条目后丢失所有条目的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能从NSMutableArray中删除[NSNull Null]对象?

将 NSMutableArray 中的所有值相加并根据普通分段控制乘以值

NSMutablearray 崩溃删除对象

NSMutableArray - 在删除时禁用重新索引

从 PLIST 中的 NSMutableArray 中删除项目

Google 表格:我可以删除公式中范围的最后一个条目吗?