Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/122.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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 多线程环境中的PersistentStore协调器原因“;“未找到店铺”;崩溃_Ios_Multithreading_Core Data - Fatal编程技术网

Ios 多线程环境中的PersistentStore协调器原因“;“未找到店铺”;崩溃

Ios 多线程环境中的PersistentStore协调器原因“;“未找到店铺”;崩溃,ios,multithreading,core-data,Ios,Multithreading,Core Data,Managedobjectcontextsave:对NSOperation子类的查询导致此异常。我不确定这里出了什么问题,但似乎是线程锁定问题。有人能帮我解决这个问题吗 多个子类使用一个PSC,每个子类都有自己的MOC。也许我需要把@synchronized放在某个地方以保证线程安全 Fatal Exception: NSInternalInconsistencyException This NSPersistentStoreCoordinator has no persistent stor

Managedobjectcontext
save:
NSOperation
子类的查询导致此异常。我不确定这里出了什么问题,但似乎是线程锁定问题。有人能帮我解决这个问题吗

多个子类使用一个PSC,每个子类都有自己的MOC。也许我需要把
@synchronized
放在某个地方以保证线程安全

Fatal Exception: NSInternalInconsistencyException

This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation.

Thread : Fatal Exception: NSInternalInconsistencyException

0  CoreFoundation                 0x3018af0b __exceptionPreprocess + 130
1  libobjc.A.dylib                0x3a921ce7 objc_exception_throw + 38
2  CoreData                       0x2fedd689 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 3228
3  CoreData                       0x2fefef49 -[NSManagedObjectContext save:] + 824
4  ChevronRetail                  0x0006aae5 -[MyParseOperation myMethod:] (MyParseOperation.m:159)
5  ChevronRetail                  0x0006adbf -[MyParseOperation main] (StationFinderParseOperation.m:192)
6  Foundation                     0x30abe875 -[__NSOperationInternal _start:] + 772
7  Foundation                     0x30b62745 __NSOQSchedule_f + 60
其他信息: PersistentStoreCoordinator保存在多个控制器中的MOC访问的appdelegate中

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {  
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }        
    NSString *documentsDirectoryPath = [self applicationDocumentsDirectory];

    NSString *storePath = [documentsDirectoryPath stringByAppendingPathComponent:@"MyDatabase.sqlite"];
    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];   
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    NSError *error;

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
    {

    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    //abort();
    }
    return _persistentStoreCoordinator;
}


- (NSManagedObjectContext *)managedObjectContext {

    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

    if (coordinator != nil) {
        _managedObjectContext = [NSManagedObjectContext new];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    [_managedObjectContext setMergePolicy:NSOverwriteMergePolicy];
    return _managedObjectContext;
}

苹果样板PSC初始化代码不是线程安全的(MOC初始化代码也不是线程安全的)。
您可以找到类似的问题

在多线程环境中,2个(或更多)线程可以调用PSC初始化代码。
解决方法是在“应用程序确实完成了启动…”中添加以下行:

发出使用CoreData堆栈的任何操作/流之前。
这可以确保只有一个线程(主线程)初始化堆栈,但是这否定了当前实现试图实现的“延迟加载”原则。

错误的原因是这种执行流:

线程1测试是否存在一个
\u persistentstorecordinator
,并找到它为零。
线程2测试是否存在一个
\u persistentstorecordinator
,并找到它为零。
线程1和线程2继续进入初始化代码部分。
线程1到达该行(但尚未返回):

线程2执行该行:

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
线程1返回一个没有存储的协调器,并在初始化私有MOC、保存MOC和崩溃的操作中使用它。

为了保持“延迟加载”梦想的活力,您可以通过以下方式实现初始化代码:

//UNTESTED
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {//someone already initilized this part of the stack
        return _persistentStoreCoordinator;//no need to lock
    }
    @synchronized(self) {
        if (_persistentStoreCoordinator == nil) {//check under lock
            _persistentStoreCoordinator = [self __persistentStoreCoordinator];//only one thread could set the ivar
        }
    }
    return _persistentStoreCoordinator;
}


- (NSPersistentStoreCoordinator*) __persistentStoreCoordinator
{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyDatabase.sqlite"];
    NSError *error = nil;
    NSPersistentStoreCoordinator* coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                   configuration:nil
                                             URL:storeURL
                                         options:options
                                           error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    return coordinator;//always return a full fledged coordinator
}
您可以使用任何您喜欢的同步机制来防止这种竞争状况,这只是一个简单的例子。

此竞争条件也适用于
managedObjectModel
managedObjectContext


解决方案类似。

添加MOC和PSC初始化代码目前没有时间形成答案,但在PSCThanks的初始化中有一个竞赛条件,这很有帮助-目前每个控制器都有自己的MOC,因此我认为不应该有竞赛条件。在将更新推送到存储区之前,是否有办法测试此代码?--问题是我在个人测试期间从未见过崩溃,但在商店中我看到了很多崩溃。在访问协调器期间暂停线程,并尝试重现您认为导致错误的竞争条件。
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
//UNTESTED
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {//someone already initilized this part of the stack
        return _persistentStoreCoordinator;//no need to lock
    }
    @synchronized(self) {
        if (_persistentStoreCoordinator == nil) {//check under lock
            _persistentStoreCoordinator = [self __persistentStoreCoordinator];//only one thread could set the ivar
        }
    }
    return _persistentStoreCoordinator;
}


- (NSPersistentStoreCoordinator*) __persistentStoreCoordinator
{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyDatabase.sqlite"];
    NSError *error = nil;
    NSPersistentStoreCoordinator* coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                   configuration:nil
                                             URL:storeURL
                                         options:options
                                           error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    return coordinator;//always return a full fledged coordinator
}