CoreData 对象未在屏幕之间保存

Posted

技术标签:

【中文标题】CoreData 对象未在屏幕之间保存【英文标题】:CoreData objects not saved between screens 【发布时间】:2015-03-14 10:39:53 【问题描述】:

我有一个包含UITableView 的屏幕,在这个屏幕中我有一个NSManagedObjects 数组。它工作得很好,但是当我尝试移动到另一个屏幕(单击特定单元格,然后推送一个新屏幕),然后返回到同一个 UITableView 屏幕时,所有对象都丢失了。

这是什么意思?我尝试打印NSManagedObjects 的数组,这很好,所有对象都在那里,但是当我打印每个对象的描述时,我从所有对象属性中得到nil

有人知道是什么原因吗?我不知道为什么,但它在 12 小时前运行良好,但现在一切都搞砸了,我不知道我做了什么。

提前致谢!

保存方法:

- (void)saveContext 
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) 
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) 
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        
        else 
            NSLog(@"Context saved!");
        
    

这就是我保存对象的方式:

NSDictionary *response = responseObject;
if ([[response valueForKey:@"status"] rangeOfString:@"ok"].location != NSNotFound)

   NSArray *data = [response objectForKey:@"data"];
   if (data.count != 0)
   
       if (page.integerValue == 0) 
           [[DownloadData sharedData] deleteAllObjectsFromEntityName:@"DbHomeCuisine"];
           [[DownloadData sharedData] deleteAllObjectsFromEntityName:@"DbHomeCategory"];
           [[DownloadData sharedData] deleteAllObjectsFromEntityName:@"DbHomeDish"];
       

       NSMutableArray *homePageObjects = [[NSMutableArray alloc] initWithCapacity:data.count];
       for (NSDictionary *object in data)
       
           NSNumber *type = [object objectForKey:@"type"];
           switch (type.integerValue) 
               case 1:
               
                   NSDictionary *content = [object objectForKey:@"content"];
                   NSManagedObjectContext *context = [[MainDb sharedDb] managedObjectContext];
                   DbHomeCuisine *homeCuisine = [NSEntityDescription insertNewObjectForEntityForName:@"DbHomeCuisine" inManagedObjectContext:context];
                   NSInteger cuisineId = [[content valueForKey:@"cuisine_id"] integerValue];
                   homeCuisine.cuisine = [self gCuisineWithCuisineId:[NSNumber numberWithInteger:cuisineId]];
                   NSInteger count = [[content valueForKey:@"count"] integerValue];
                   homeCuisine.count = [NSNumber numberWithInteger:count];
                   homeCuisine.type = type;
                   [homePageObjects addObject:homeCuisine];
               
                   break;

               case 2:
               
                   NSDictionary *content = [object objectForKey:@"content"];
                   NSManagedObjectContext *context = [[MainDb sharedDb] managedObjectContext];
                   DbHomeCategory *homeCategory = [NSEntityDescription insertNewObjectForEntityForName:@"DbHomeCategory" inManagedObjectContext:context];
                   NSInteger categoryId = [[content valueForKey:@"category_id"] integerValue];
                   homeCategory.category = [self gCategoryWithCategoryId:[NSNumber numberWithInteger:categoryId]];
                   NSInteger count = [[content valueForKey:@"count"] integerValue];
                   homeCategory.count = [NSNumber numberWithInteger:count];
                   homeCategory.type = type;
                   [homePageObjects addObject:homeCategory];
               
                   break;

               case 3:
               
                   NSDictionary *content = [object objectForKey:@"content"];
                   NSManagedObjectContext *context = [[MainDb sharedDb] managedObjectContext];
                   DbHomeDish *homeDish = [NSEntityDescription insertNewObjectForEntityForName:@"DbHomeDish" inManagedObjectContext:context];
                   homeDish.dishId          = [self gInt:content forKey:@"dish_id"];
                   homeDish.headline        = [AppUtils checkForEmptyValue:[content valueForKey:@"title"]];
                   homeDish.text            = [AppUtils checkForEmptyValue:[content valueForKey:@"description"]];
                   homeDish.cuisineId       = [self gInt:content forKey:@"cuisine_id"];
                   homeDish.cuisine         = [self gCuisineWithCuisineId:homeDish.cuisineId];
                   homeDish.creationDate    = [AppUtils checkForEmptyValue:[content valueForKey:@"creation_time"]];
                   homeDish.userId          = [self gInt:content forKey:@"user_id"];
                   homeDish.longitude       = [self gDouble:content forKey:@"lng"];
                   homeDish.latitude        = [self gDouble:content forKey:@"lat"];
                   homeDish.lastPromoteDate = [AppUtils checkForEmptyValue:[content valueForKey:@"last_promote_time"]];
                   homeDish.price           = [self gInt:content forKey:@"price"];
                   homeDish.currency        = [AppUtils checkForEmptyValue:[content valueForKey:@"currency"]];
                   homeDish.countryName     = [AppUtils checkForEmptyValue:[content valueForKey:@"country_name"]];
                   homeDish.baseCurrency    = [self gFloat:content forKey:@"base_currency"];
                   homeDish.exchangeRate    = [self gFloat:content forKey:@"exchange_rate"];
                   homeDish.countryIsoCode  = [AppUtils checkForEmptyValue:[content valueForKey:@"country_iso_code"]];
                   homeDish.mainPhoto       = [AppUtils checkForEmptyValue:[content valueForKey:@"main_photo"]];
                   homeDish.like            = [self gLikeWithDishId:homeDish.dishId];
                   homeDish.profileImageURL = [AppUtils checkForEmptyValue:[content valueForKey:@"profile_img_url"]];
                   homeDish.likeCount       = [self gInt:content forKey:@"likes"];
                   homeDish.type            = type;
                   [homePageObjects addObject:homeDish];
               
                   break;

               default:
                   break;
           
       

       //   @@log -- Save data to core data and device
       //
       //
       [[MainDb sharedDb] saveContext];

       if (success) 
           success(operation, homePageObjects);
       
   

【问题讨论】:

显示数据模块、保存和 UI 转换的代码 @Wain 在我的核心数据模型中有 15 个实体...如何显示它们?保存是基础 CoreData 保存。 UI 的过渡是 UINavigationController 的简单推送。 你怎么回来的?我们不需要所有实体,只需要一个关于如何更新和保存模型的示例,然后再次查询它。过渡部分更多的是关于你回到什么。目前,您的问题是一个广泛的“猜测我可能做错了什么”,因为这是无法回答的...... @Wain 转换都是普通的 Push 和 Pop 方法。我忘记了另一件重要的事情,当我弹出屏幕并返回 UITableView 并显示 nil 对象时,我得到了与推动控制器之前看到的相同的 3 个对象,当我向下滚动 UITableView 控制器时,我得到了那些3 重新来过。 我假设您正在使用viewDidLoad: 方法查询您的数据库?还是类似的?您发布的代码看起来不错:您将什么记录到调试器中?您的托管对象似乎正在被释放。 【参考方案1】:

说真的,您应该考虑使用NSFetchedResultsController 进行重构。从 Xcode 中提供的模板开始(New Project -> Master/Detail -> check Core Data,代码在MasterViewController.m)。

我强烈反对将 Core Data 对象加载到要在表格视图中显示的数组中。您的问题是此类设置的典型问题,您最终也会遇到内存和性能问题。

【讨论】:

以上是关于CoreData 对象未在屏幕之间保存的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中将 CoreData 保存/同步到 iCloud

NSPredicate 未在 CoreData 中返回 Int32

保存期间CoreData比较错误

CoreData 通过 Quit 保存对象更改

将屏幕截图保存到CoreData

保存循环删除多对多CoreData关系的一端