Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.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 核心数据重复_Ios_Core Data - Fatal编程技术网

Ios 核心数据重复

Ios 核心数据重复,ios,core-data,Ios,Core Data,我尝试使用NSManagedDocument构建一种在核心数据中保存数据的现代方法。一切正常,但如果我重新启动应用程序(终止并再次运行),我会在数据库中获得重复的实体,有时应用程序会因错误而崩溃: 此NSPersistentStoreCoordinator没有持久存储。它不能 执行保存操作 我认为在不同的线程中发生了一些事情并制造了麻烦,但我不知道我必须改变什么。希望你们中的一个能帮助我 我的名为Database的类具有以下实现 + (Database *)sharedDatabase { st

我尝试使用
NSManagedDocument
构建一种在核心数据中保存数据的现代方法。一切正常,但如果我重新启动应用程序(终止并再次运行),我会在数据库中获得重复的实体,有时应用程序会因错误而崩溃:

此NSPersistentStoreCoordinator没有持久存储。它不能 执行保存操作

我认为在不同的线程中发生了一些事情并制造了麻烦,但我不知道我必须改变什么。希望你们中的一个能帮助我

我的名为
Database
的类具有以下实现

+ (Database *)sharedDatabase
{
static Database *sharedInstance;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    url = [url URLByAppendingPathComponent:@"Default Database"];
    sharedInstance = [[self alloc] initWithFileURL:url];
    sharedInstance.isCreating = NO;
    sharedInstance.isOpening = NO;
});
if (![[NSFileManager defaultManager] fileExistsAtPath:[sharedInstance.fileURL path]]) {
    if (!sharedInstance.isCreating) {
        sharedInstance.isCreating = YES;
        [sharedInstance saveToURL:sharedInstance.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
            sharedInstance.isCreating = NO;
        }];
    }
} else if(sharedInstance.documentState == UIDocumentStateClosed){
    if (!sharedInstance.isOpening) {
        sharedInstance.isOpening = YES;
        [sharedInstance openWithCompletionHandler:^(BOOL success) {
            sharedInstance.isOpening = NO;
        }];
    }
}
return sharedInstance;
}
然后我用一个名为
Book
的实体创建了一个数据模型。为了保持简单,它只有一个
isbn
(类型为
NSString
)作为属性。 对于
NSManagedObject
子类
图书
的类别
Create
(Xcode自动生成的子类),有以下实现来检查数据库中是否已经存在ISBN。这应该返回一个新创建的实体或现有实体,当出现错误时(如有两本书具有相同的ISBN)返回nil

+(Book *) bookWithISBN:(NSString *)isbn inManagedObjectContext:(NSManagedObjectContext *)context
{
Book *book;

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Book"];
request.predicate = [NSPredicate predicateWithFormat:@"isbn LIKE %@", isbn];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"isbn" ascending:YES];
request.sortDescriptors = @[sortDescriptor];

NSError *error;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (!matches || (matches.count > 1)) {
    return nil;
} else if(matches.count == 0){
    book = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:context];
    book.isbn = isbn;
}else{
    book = [matches lastObject];
}
return book;
}
因此,现在如果我通过调用托管对象上下文:[Database sharedDatabase].managedObjectContext]中的
[bookWithISBN:@“1234567890”调用此方法,则在我第一次运行应用程序时,它将在我的数据库中创建一个实体。如果我终止应用程序并再次运行它,它会再次创建相同的实体。第二次我终止并再次运行它时,它返回
nil
(应该如此,因为有两本书具有相同的ISBN)

我在这个项目中使用ARC

可能的解决方案


我已经做了几个小时的实验,直到现在,如果我不将
UIManagedDocument
子类化,而是创建一个继承自
NSObject
并包含
UIManagedDocument
的类,它似乎是有效的。有人知道这真的是正确的解决方案吗?因为我认为应该可以将
UIManagedDocument

子类化,所有实例化代码都必须驻留在dispatch\u once块中。您希望确保只打开文档一次

此链接显示所有实例化代码必须位于dispatch_once块内


这个建议不能解决你眼前的问题,但我还是会把它说出来的。在我发现MagicalRecord之前,我一直像你一样使用原始形式的coreData。太棒了。你应该去看看


好处是它将所有CoreData代码打包成整洁的可消化代码。它负责管理线程中的上下文关系。

我想我自己找到了一个解决方案。如果我在设置请求谓词时将=替换为LIKE,则在我的示例中它会起作用。我将在我的真实应用程序中测试它,这个应用程序要复杂得多,明天会给出响应。我只是不明白为什么在第二次“重新运行”的情况下“=”会正常工作。您最初是使用“=”还是“=”?我最初使用的是单个“=”,您应该使用“=”进行比较。试一下。现在试了大约5次后,我就停止工作了。我认为这个问题在某种程度上与managedObjectContext有关。我尝试将打开和创建操作包含到dispatch_once块中,没有任何更改,谢谢。我会试一试的。我在一年多前就试过了,觉得这真的很复杂,但也许今天我对所有的术语都有了更好的理解