在创建新实体之前删除CoreData实体不起作用

时间:2014-04-10 04:41:36

标签: ios core-data

基本上我试图在调用Web服务以收集最新数据之前,在视图加载时简单地清除CoreData实体(因为数据将经常从多个平台更新)。但是,当我实现删除实体代码时,我的表视图中不会出现任何数据。我检查了在我的视图中何时触发代码并且它似乎被称为正确的顺序。

2014-04-09 21:13:21.113 Karmo[28531:60b] Delete code being called
2014-04-09 21:13:21.122 Karmo[28531:60b] SetUpData being called
2014-04-09 21:13:21.123 Karmo[28531:60b] FetchData being called

如果我注释掉删除代码,则显示所有数据(但由于在获取新数据之前未删除旧数据,因此它会重复)。感觉我可能会错过一些小事。任何帮助将不胜感激。下面我已经包含了viewDidLoad,delete,setUp和fetch代码。

- (void)viewDidLoad {

  [super viewDidLoad];

  //Delete entities from Core Data
  [self deleteEntityData];

  //Call the API and store the data to Core Data
  [self setUpData];}




- (void) deleteEntityData {

//Delete All Old Exlpore View Entities in Core Data

NSLog(@"Delete code being called");

NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:[NSEntityDescription entityForName:@"ExploreView" inManagedObjectContext:context]];
[fetch setIncludesPropertyValues:NO];

NSError *error = nil;
NSArray *entities = [context executeFetchRequest:fetch error:&error];
for (NSManagedObject * exploreView in entities) {
    [context deleteObject:exploreView];

    if (![context save:&error]) {
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    };

}

}




- (void) setUpData {

//Create the string with the userID for the get request here
NSLog(@"SetUpData being called");

//Initialize AFHTTPRequestOperationManager with Dribbble API base URL
_operationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.karmo.com/explore/index"]];

[_operationManager GET:@"?user_id=XXXX" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

//Code to set up new Core Data Entity 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {


    NSLog(@"Failed to fetch shots from Karmo API!");
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Unable to Connect"
                                                   message:@"We were not able to connect to the karmo database. Some data may be out of date."
                                                  delegate:self
                                         cancelButtonTitle:@"Ok"
                                         otherButtonTitles: nil];
    [alert show];

} ];

[self fetchData];}




- (void) fetchData {

NSLog(@"FetchData being called");

[exploreSortData removeAllObjects];
[exploreTableData removeAllObjects];
self.timeSortButton.backgroundColor = [UIColor clearColor];
self.voteSortButton.backgroundColor = [UIColor lightGrayColor];
NSMutableArray *subPredicates = [[NSMutableArray alloc] init];

// Fetch the recipes from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"ExploreView"];
exploreSortData = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

//Would probably need to call the category slelctions here. Use an if statment to capture so if non are seletced that all the categories are displayed

if ([selectedCategoriesFilter count] > 0 ) {

    for (int i = 0; i < [selectedCategoriesFilter count]; i++) {
        NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"category ==[c] %@",[[selectedCategoriesFilter objectAtIndex:i]valueForKey:@"categorySelected"]];
        [subPredicates addObject:newPredicate];

    }


    NSPredicate *combinedPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];

    NSArray *filterData = [[NSArray alloc]init];
    filterData = [exploreSortData filteredArrayUsingPredicate:combinedPredicate];

    NSSortDescriptor *voteDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"totalVotes" ascending:NO];

    NSMutableArray * descriptors = [[NSArray arrayWithObjects:voteDescriptor, nil]mutableCopy];
    exploreTableData  = [[filterData sortedArrayUsingDescriptors:descriptors]mutableCopy];
    [self.tableView reloadData];


} else {

    NSSortDescriptor *voteDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"totalVotes" ascending:NO];

    NSMutableArray * descriptors = [[NSArray arrayWithObjects:voteDescriptor, nil]mutableCopy];
    exploreTableData  = [[exploreSortData sortedArrayUsingDescriptors:descriptors]mutableCopy];
    [self.tableView reloadData];


}

}

2 个答案:

答案 0 :(得分:0)

我认为您需要在从服务器删除或更新数据后调用[self.tableView reloadData]。所以你可能会错过调用reloadData。

不相关,但我在代码中注意到的另一件事是您在for循环中调用[context save:&error]。您应该将其移出for循环以提高性能。单个[上下文保存]将保存您在for循环中所做的所有删除。

答案 1 :(得分:0)

注意区别 - 删除CoreData实体,不会立即释放与它们关联的NSManagedObjects!

您的代码可能会保留您刚刚删除的那些实体(在数组或字典中,或者只是作为某个类的成员),因此,您的tableView仍然“看到”这些对象。

通常,为了远离这些问题,您可以使用为“Entity”(与“Class”)配置的NSArrayController,并将tableView绑定到该阵列控制器。 ArrayController正在对实体进行处理,而不是它们的对象表示,因此在删除或添加实体时它将保持同步。