2013-02-26 3 views
0

NSManagedDocument을 사용하여 코어 데이터에 데이터를 저장하는 현대적인 방법을 만들려고했습니다. 모든 제외하고 잘 작동되는 나는 응용 프로그램을 (를 종료하고 다시 실행) 나는 오류 내 데이터베이스에서 엔티티 때로는 응용 프로그램 충돌을 중복 얻을 것이다 다시 시작하면 : 나는에서 무슨 일이 있다고 생각코어 데이터에서 중복 됨

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

스레드가 다르며 문제를 일으키지 만 변경해야 할 부분을 파악할 수 없습니다. 당신 중 한 명이 나를 도울 수 있기를 바랍니다.

Database라는 내 클래스는 하나의 엔티티와 데이터 모델이 Book라는

+ (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; 
} 

후 제작 한이 구현에게 있습니다. 단순하게 유지하기 위해 isbn (유형은 NSString 임)을 속성으로 사용합니다. NSManagedObject 하위 클래스 (Xcode 자동 생성 하위 클래스)의 범주 Create에는 ISBN이 데이터베이스에 있는지 여부를 확인하기위한 다음 구현이 있습니다. 같은 ISBN을 가진 2 권의 책을 가지고있는 것처럼 오류가 발생하면 새로 생성 된 엔티티 또는 기존 엔티티를 반환하고 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; 
} 

그래서 지금은 [Book bookWithISBN:@"1234567890" inManagedObjectContext:[Database sharedDatabase].managedObjectContext] 나는 그것이 내 데이터베이스에서 엔티티를 생성합니다 응용 프로그램을 처음 실행할 때 호출하여이 메소드를 호출합니다. 앱을 종료하고 다시 실행하면 같은 엔티티가 한 번 더 생성됩니다. 그리고 두 번째로 종료하고 다시 실행하면 nil (동일한 ISBN이있는 2 권의 책이 있어야하기 때문에)을 반환합니다.

이 프로젝트에서는 ARC를 사용하고 있습니다.

가능한 해결 :

내가 지금 몇 시간을 실험하고 전까지 된 지금 내가 NSObject에서 상속과 UIManagedDocument를 포함하는 클래스를 만드는 대신 UIManagedDocument를 서브 클래스 화해 해달라고하면 작동하는 것 같다. 누군가가 정말로 그것이 올바른 해결책이라는 것을 알고 있습니까? UIManagedDocument을 서브 클래스화할 수 있어야한다고 생각하기 때문입니다.

+0

나는 해결책을 스스로 찾았다 고 생각한다. 만약 내가 바꿀 = LIKE로 요청을 설정하면 내 예제에서 작동합니다. 나는 훨씬 더 복잡하고 내일 응답을 줄 것이다 내 애플 리케이션에서 그것을 테스트 할게. 나는 왜 '='가 두 번째 '재실행'의 경우에 올바르게 작동하는지 알지 못한다. – Bohrnsen

+0

원래 "="또는 "=="를 사용 했습니까? – sosborn

+0

i는 single = '원래'를 사용했습니다. – Bohrnsen

답변

0

모든 인스턴스화 코드는 dispatch_once 블록 내에 있어야합니다. 문서를 한 번만 열어 보려고합니다.

이 링크는 모든 인스턴스화 코드가 dispatch_once 블록 내에 있어야 함을 나타냅니다.

How do I implement an Objective-C singleton that is compatible with ARC?

+0

변경 사항없이 dispatch_once 블록에 작업을 생성하고 열기를 포함 시키려고했습니다. – Bohrnsen

1

이 제안은 즉각적인 문제가 해결되지 않습니다,하지만 난 어쨌든 그것을 놓을 게요. 나는 MagicalRecord를 발견 할 때까지 당신처럼 원시 형식의 coreData를 사용했습니다. 그것은 굉장합니다. 그것을 확인해야합니다. https://github.com/magicalpanda/MagicalRecord

이점은 모든 CoreData 코드를 깔끔한 소화 가능 코드로 패키징한다는 점입니다. 또한 스레드에서 컨텍스트 관계를 관리합니다.

+0

감사합니다. 나는 그것을 시험해 보겠다. – Bohrnsen

+0

학습 곡선을 전혀 사용하지 않아도 아주 간단하다. –

+0

나는 이것을 실제로 1 년 또는 그 이상 동안 시도해 보았고 그것이 정말로 복잡해 졌다고 생각했지만 어쩌면 오늘 모든 용어에 대해 더 잘 이해할 수있을 것이라고 생각했다. – Bohrnsen