在我更新我的核心数据存储后 - 通过删除然后添加数据 - 在另一个线程中,我需要更改屏幕然后返回数据以更新它。有没有办法更新Core Data而无需更改应用程序中的屏幕?
重置数据库的代码:
- (void) resetDatabase {
count++;
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
ConDAO *con = [[ConDAO alloc] init];
DatabaseManager *manager = [DatabaseManager sharedManager];
NSError * error;
NSURL * storeURL = [[[manager managedObjectContext] persistentStoreCoordinator] URLForPersistentStore:[[[[manager managedObjectContext] persistentStoreCoordinator] persistentStores] lastObject]];
[[manager managedObjectContext] reset];//to drop pending changes
if ([[[manager managedObjectContext] persistentStoreCoordinator] removePersistentStore:[[[[manager managedObjectContext] persistentStoreCoordinator] persistentStores] lastObject] error:&error])
{
// remove the file containing the data
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
//recreate the store like in the appDelegate method
[[[manager managedObjectContext] persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];//recreates the persistent store
}
NSLog(@"*****************************");
NSLog(@"updating");
NSLog(@"count: %d", count);
NSLog(@"*****************************");
[self populateDatabase:0 con:con];
NSTimer *timer = [NSTimer timerWithTimeInterval:60.0
target:self
selector:@selector(resetDatabase)
userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
dispatch_async(dispatch_get_main_queue(), ^(void){
});
});
}
更改ui时运行的代码:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// Setup KVO for verifyingcard
[self addObserver:self forKeyPath:@"verifyingCard" options:NSKeyValueObservingOptionNew context:nil];
if([BluetoothTech isEqualToString:@"BLE"]){
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey: @YES}];
}
else if([BluetoothTech isEqualToString:@"HID"]){
[self.bluetoothScanTextView becomeFirstResponder];
}
[self loadStudents];
}
我认为它与loadStudents()函数有关,但是当我使用NSNotificationCenter从其他类运行它时,它仍然无效。
LoadStudent代码:
- (void)loadStudents{
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Caf_student_cards"];
NSArray *arr = [[self.manager managedObjectContext] executeFetchRequest:fetchRequest error:&error];
for(int i = 0; i < [arr count]; i++){
if([[[arr objectAtIndex:i] valueForKey:@"user_id"] isEqualToString:@"201509061"]){
NSLog(@"%@",[arr objectAtIndex:i]);
}
}
if(!error){
self.caf_student_cards = [NSMutableArray arrayWithArray:arr];
self.keys = [[[arr.firstObject entity] attributesByName] allKeys];
}
else{
NSLog(@"%s %s %s","\n\n\n",[[error localizedDescription] UTF8String],"\n\n\n");
dispatch_async(dispatch_get_main_queue(), ^{
// Show alert to tell user to reload this page
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Error: %@", [error localizedDescription]] message:@"Check connection and relog back into cafeteria." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
});
}
}
答案 0 :(得分:2)
此代码存在多个问题。
与您的问题最直接相关的是您正在更新持久性商店,但不更新您的用户界面。它不会自动发生。如果您有新数据,则需要告知UI更新。如何做到这一点取决于您拥有的UI类型。如果它是一个表视图,它可能就像告诉表视图重新加载其数据一样简单。如果你有一个用来保存UI数据的数组,你也需要更新它(看起来这可能是代码中的caf_student_cards
但是无法确定。
其他问题 - 这些是您需要立即解决的主要问题:
dispatch_async
在这里无效。您需要在托管对象上下文中使用performBlock
或performBlockAndWait
,或者在持久容器上使用performBackgroundTask
。delete
对象,或者使用NSBatchDeleteRequest
。可能还有其他人。这段代码很乱。如果你花一点时间查看Apple的Core Data Programming Guide,那么你会为自己做一件大事。
此外,您keep几乎询问了same个问题repeatedly。你有一些很好的建议,但你似乎没有采取任何建议。如果您想了解更多信息,请阅读以前在您发布此问题时已经提供的其他答案。