基本上我试图在调用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];
}
}
答案 0 :(得分:0)
我认为您需要在从服务器删除或更新数据后调用[self.tableView reloadData]
。所以你可能会错过调用reloadData。
不相关,但我在代码中注意到的另一件事是您在for循环中调用[context save:&error]
。您应该将其移出for循环以提高性能。单个[上下文保存]将保存您在for循环中所做的所有删除。
答案 1 :(得分:0)
注意区别 - 删除CoreData实体,不会立即释放与它们关联的NSManagedObjects!
您的代码可能会保留您刚刚删除的那些实体(在数组或字典中,或者只是作为某个类的成员),因此,您的tableView仍然“看到”这些对象。
通常,为了远离这些问题,您可以使用为“Entity”(与“Class”)配置的NSArrayController,并将tableView绑定到该阵列控制器。 ArrayController正在对实体进行处理,而不是它们的对象表示,因此在删除或添加实体时它将保持同步。