Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ios-手动调用ViewWillAppease()时出错(Objective-C)_Ios_Objective C_Xcode_Multithreading_Core Data - Fatal编程技术网

ios-手动调用ViewWillAppease()时出错(Objective-C)

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

我正在尝试在我的ios应用程序的后台更新核心数据,我首先删除核心数据,然后再添加回来。然而,我需要一个特定的阶段来运行某些函数,但是当我尝试在后台执行所有操作时,这些函数永远不会运行,除非我更改页面并返回

因此,我试图通过手动调用viewwillappease()来修复此错误,但出现以下错误

*** 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
    并使用传递给它的上下文
  • 你不能只是删除核心数据下的文件,然后期望这些东西能正常工作。首先,在删除文件时,可能会有许多其他managedObjectContext读取或写入。第二个核心数据可以设置为对某些实体使用外部存储,这些实体将存储在单独的文件中。第三,iOS使用WAL模式进行SQLite日志记录,任何核心数据持久化存储都可能有(可能很大)日志文件
  • 要更新核心数据更改的UI,应使用NSFetchedResultsController。确保在核心数据设置中设置
    persistentcainer.viewContext.automaticallyMergesChangesFromParent=YES
  • 不要保留任何指向managedObjects的指针。它们可以在您不知情的情况下从上下文中删除,然后访问它们将导致崩溃。相反,使用fetchedResultsController-即使只针对一个对象
  • 要删除核心数据中的所有实体,请执行以下操作:

    [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
    并使用传递给它的上下文
  • 你不能只是删除核心数据下的文件,然后期望这些东西能正常工作。首先,在删除文件时,可能会有许多其他managedObjectContext读取或写入。第二个核心数据可以设置为对某些实体使用外部存储,这些实体将存储在单独的文件中。第三,iOS使用WAL模式进行SQLite日志记录,任何核心数据持久化存储都可能有(可能很大)日志文件
  • 要更新核心数据更改的UI,应使用NSFetchedResultsController。确保在核心数据设置中设置
    persistentcainer.viewContext.automaticallyMergesChangesFromParent=YES
  • 不要保留任何指向managedObjects的指针。它们可以在您不知情的情况下从上下文中删除,然后访问它们将导致崩溃。相反,使用fetchedResultsController-即使只针对一个对象
  • 要删除核心数据中的所有实体,请执行以下操作:

    [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