を使用して Core Data にデータを保存する最新の方法を構築しようとしました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;
}
次に、 という 1 つのエンティティを含むデータ モデルを作成しましたBook
。シンプルにするために、isbn
(タイプのNSString
) as 属性しかありません。サブクラス(Xcode 自動生成サブクラス)のカテゴリCreate
には、データベースに ISBN が既に存在するかどうかを確認する次の実装があります。これは、新しく作成されたエンティティまたは既存のエンティティを返し、同じ ISBN の本が 2 冊あるなどのエラーが発生した場合は nil を返します。NSManagedObject
Book
+(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;
}
[Book bookWithISBN:@"1234567890" inManagedObjectContext:[Database sharedDatabase].managedObjectContext]
したがって、アプリケーションを初めて実行するときにこのメソッドを呼び出すと、データベースにエンティティが作成されます。アプリを終了して再度実行すると、同じエンティティがもう一度作成されます。そして、2回目に終了して再度実行すると、返されますnil
(同じISBNの本が2冊あるためです)。
このプロジェクトでは ARC を使用しています。
考えられる解決策:
私は今数時間実験してきましたが、サブクラスUIManagedDocument
化せず、代わりNSObject
にUIManagedDocument
. それが本当に正しい解決策であることを誰かが知っていますか?をサブクラス化できるはずだと思うからUIManagedDocument
です。