私のiosアプリケーションのバックグラウンドでコアデータを更新しようとしていますが、まずコアデータを削除してから追加します。しかし、いくつかの関数を実行するには特定のセグが必要ですが、バックグラウンドですべてを実行しようとすると、ページを変更して元に戻さない限り、これらの関数は決して実行されません。viewWillAppear()を手動で呼び出すときのiosエラー(Objective-C)
私は手動でviewWillAppear()を呼び出してこのエラーを修正しようとしましたが、次のエラーが発生します。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x17191c00 of class CardScanView was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x16d99c30> (
<NSKeyValueObservance 0x16dcdf20: Observer: 0x17191c00, Key path: verifyingCard, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x16d5db30>
エラーが発生したクラスのメソッド:
- (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){
CardScanView *card = [[CardScanView alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:card
selector:@selector(viewWillAppear:)
name:@"updated" object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"updated" object:nil];
});
});
}
viewWillAppearとviewDidDissapear他のクラス:
- (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];
}
- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
// Disconnect the bluetooth peripheral device if it exists
if(self.discoveredPeripheral != nil){
[self.centralManager cancelPeripheralConnection:self.discoveredPeripheral];
}
// Remove KVO for verifyingCard
[self removeObserver:self forKeyPath:@"verifyingCard"];
}
エラーの原因といただきました、にもむしろこれにアプローチするより良い方法があります手動でviewDidLoadを呼び出すよりも?ありがとう
60秒ごとに?それは反パターンです。 – bbum
どうすれば更新できますか? – King
プッシュ通知に基づくデルタ更新が理想的です。ポーリングは避けなければならない。すべてのデータを削除し、データベース全体をゼロから再作成するのは最悪です。あなたはすでに持っているものを再現するだけで、1トンのバッテリー寿命を生み出す仕事をしています(データベースの内容が60秒ごとに完全に変更されないと仮定して)。 – bbum