ios-手动调用ViewWillAppease()时出错(Objective-C)
我正在尝试在我的ios应用程序的后台更新核心数据,我首先删除核心数据,然后再添加回来。然而,我需要一个特定的阶段来运行某些函数,但是当我尝试在后台执行所有操作时,这些函数永远不会运行,除非我更改页面并返回 因此,我试图通过手动调用viewwillappease()来修复此错误,但出现以下错误ios-手动调用ViewWillAppease()时出错(Objective-C),ios,objective-c,xcode,multithreading,core-data,Ios,Objective C,Xcode,Multithreading,Core Data,我正在尝试在我的ios应用程序的后台更新核心数据,我首先删除核心数据,然后再添加回来。然而,我需要一个特定的阶段来运行某些函数,但是当我尝试在后台执行所有操作时,这些函数永远不会运行,除非我更改页面并返回 因此,我试图通过手动调用viewwillappease()来修复此错误,但出现以下错误 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance
*** 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>
VIEW将在其他类中显示,VIEWDIDDISAPEAR:
- (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更好的方法?谢谢您不应该自己调用
viewDidLoad
,视图将出现
等方法。只有在重写这些方法时,才应该在super
上调用它们
提取要更新的正在运行的代码(看起来您在loadStudents
中已经有了该代码),并调用该方法,而不是viewwillbeen
请参见您不应该自己调用
viewDidLoad
,视图将出现
等方法。只有在重写这些方法时,才应该在super
上调用它们
提取要更新的正在运行的代码(看起来您在loadStudents
中已经有了该代码),并调用该方法,而不是viewwillbeen
看
persistentstorecordinator
的viewContext
视为只读,并且仅从主线程读取它。对核心数据的所有更改都应通过performBackgroundTask
并使用传递给它的上下文persistentcainer.viewContext.automaticallyMergesChangesFromParent=YES
[self.persistentContainer performBackgroundTask:^(NSManagedObjectContext * _Nonnull) {
NSArray* entities = context.persistentStoreCoordinator.managedObjectModel.entities;
for (NSEntityDescription* entity in entities) {
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:entity.name];
request.predicate = [NSPredicate predicateWithValue:YES];
request.returnsObjectsAsFaults = YES;
NSArray* result = [context executeFetchRequest:request error:NULL];
for (NSManagedObject* i in result) {
[context deleteObject:i];
}
}
[context save:NULL];
}];
persistentstorecordinator
的viewContext
视为只读,并且仅从主线程读取它。对核心数据的所有更改都应通过performBackgroundTask
并使用传递给它的上下文persistentcainer.viewContext.automaticallyMergesChangesFromParent=YES
[self.persistentContainer performBackgroundTask:^(NSManagedObjectContext * _Nonnull) {
NSArray* entities = context.persistentStoreCoordinator.managedObjectModel.entities;
for (NSEntityDescription* entity in entities) {
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:entity.name];
request.predicate = [NSPredicate predicateWithValue:YES];
request.returnsObjectsAsFaults = YES;
NSArray* result = [context executeFetchRequest:request error:NULL];
for (NSManagedObject* i in result) {
[context deleteObject:i];
}
}
[context save:NULL];
}];
我在执行3时遇到了问题,有什么我可以遵循的吗?我会在同一个函数中使用此新代码进行更新吗?根据您的代码,我不清楚您要监视哪些对象的更改,但您应该发出一个由NSFetchedResultsController监视的fetchRequest。将视图控制器设置为代理,然后至少实现
controllerdChangeContent:
并重新加载所有内容。一旦你开始工作,你应该实现其他的委托方法,并且只更新视图中需要更新的部分。问题是我并不是真的在更新一个表或任何东西,而是一个包含学生的字典,在我改变屏幕之前,它似乎返回null。我试图手动加载ViewWill以复制此内容,但没有成功。我还尝试了[self.view setNeedsDisplay];但这也不起作用。我可以调用一个函数来执行类似的操作吗?我可以在没有persistentContainer的情况下调用上面的delete函数吗?我的数据库管理器中没有这样的设置。简短回答:没有。如果两个上下文试图同时修改存储ar,核心数据不知道要使用哪个更改。设置mergePolicy
可以说明商店应该做什么,但这样会丢失信息。通过performBackgroundTask
(内部有一个队列)对核心数据进行所有更改(包括删除)可以解决此问题。另一种解决方案是只使用viewContext,而不使用其他背景上下文。这是一个糟糕的解决方案,因为所有的阅读和写作都在主线上,但是对于那些在处理多个上下文方面有困难的初学者来说,这更简单。我在实现3方面有困难,有什么我可以遵循的吗?我会在同一个函数中使用此新代码进行更新吗?根据您的代码,我不清楚您要监视哪些对象的更改,但您应该发出一个由NSFetchedResultsController监视的fetchRequest。将视图控制器设置为de