먼저 UIManagedDocument에 데이터를로드 한 다음 saveToURL:forSaveOperation:completionHandler:
을 실행하는 응용 프로그램이 있습니다. completionHandler 블록 내부에서이 데이터베이스의 다양한 요소에 대한 업데이트를 수행하고 완료되면 다른 저장을 수행합니다.UIManagedDocument를 저장할 때 응용 프로그램이 손상됩니다.
게다가 앱에는 데이터를 다시로드하고 데이터를 다시 업데이트하며 데이터베이스의 한 엔티티를 삭제하는 3 개의 버튼이 있습니다. 모든 버튼 방법에서 마지막 명령도 절약 효과가 있습니다.
이 모든 것을 시뮬레이터에서 실행할 때 모두 원활하게 진행됩니다. 그러나 장치에서는 그렇지 않습니다. 끊임없이 충돌합니다. 나는 일반적으로 "삭제"버튼을 누르거나 데이터베이스를 다시로드하거나 다시 업데이트 할 때 충돌이 일어나는 것을 관찰했습니다. 그리고 항상 작동은 saveToURL
입니다.
다중 스레드 데이터베이스를 저장하면 문제가 발생합니다. 기기가 코드를 더 느리게 실행하면 어쩌면 여러 절약 효과가 동시에 발생하고 앱이 올바르게 처리하지 못할 수 있습니다. 또한 삭제 버튼으로 엔티티가 삭제되지 않고 존재하지 않는다고 표시되는 경우도 있습니다.
나는 이것에 완전히 의아해하고 있으며,이 모든 저축 작업이 완료되어야합니다 ... 사실, 내가 제거하면, 앱은 더 모호하게 행동합니다.
이 문제를 해결하기 위해 무엇을 할 수 있습니까? 고마워요!
[편집] 여기서 문제가되는 코드를 게시합니다. 먼저 데이터를로드, 나는 특히이 두 가지 방법으로, 헬퍼 클래스를 사용
+ (void)loadDataIntoDatabase:(UIManagedDocument *)database
{
[database.managedObjectContext performBlock:^{
// Read from de plist file and fill the database
[database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
[DataHelper completeDataOfDatabase:database];
}];
}
+ (void)completeDataOfDatabase:(UIManagedDocument *)database
{
[database.managedObjectContext performBlock:^{
// Read from another plist file and update some parameters of the already existent data (uses NSFetchRequest and works well)
// [database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];
[database updateChangeCount:UIDocumentChangeDone];
}];
}
그리고보기
, 나는이 같은 3 개 액션 방법이 있습니다- (IBAction)deleteButton {
[self.database.managedObjectContext performBlock:^{
NSManagedObject *results = ;// The item to delete
[self.database.managedObjectContext deleteObject:results];
// [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
[self.database updateChangeCount:UIDocumentChangeDone];
}];
}
- (IBAction)reloadExtraDataButton {
[DataHelper loadDataIntoDatabase:self.database];
// [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
[self.database updateChangeCount:UIDocumentChangeDone];
}
- (IBAction)refreshDataButton {
[DataHelper completeDataOfDatabase:self.database];
//[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
[self.database updateChangeCount:UIDocumentChangeDone];
}
[편집 2 보다 코드 : 우선은 초기 뷰 viewDidLoad에이 방법을 실행 :
- (void)viewDidLoad{
[super viewDidLoad];
self.database = [DataHelper openDatabaseAndUseBlock:^{
[self setupFetchedResultsController];
}];
}
이것은 setupFetchedResultsController 방법 모습이다 같은
- (void)setupFetchedResultsController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Some entity name"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.database.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
데이터베이스의 다른 엔티티를 보여주기 위해 앱의 각보기 (탭 있음)에는 다른 setupFetchedResultsController가 있습니다.
지금, 헬퍼 클래스, 이것은 각보기의 viewDidLoad에를 통해 실행됩니다 일류 방법 :
+ (UIManagedDocument *)openDatabaseAndUseBlock:(completion_block_t)completionBlock
{
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Database"];
UIManagedDocument *database = [[UIManagedDocument alloc] initWithFileURL:url];
if (![[NSFileManager defaultManager] fileExistsAtPath:[database.fileURL path]]) {
[database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self loadDataIntoDatabase:database];
completionBlock();
}];
} else if (database.documentState == UIDocumentStateClosed) {
// Existe, pero cerrado -> Abrir
[database openWithCompletionHandler:^(BOOL success) {
[self loadDataIntoDatabase:database];
completionBlock();
}];
} else if (database.documentState == UIDocumentStateNormal) {
[self loadDataIntoDatabase:database];
completionBlock();
}
return database;
}
답장을 보내 주셔서 감사합니다. 방금 코드를 포함하도록 게시물을 편집하여 더 잘 이해했습니다. 나는 'updateChangeCount'를 가진 첫 번째 것을 제외하고는 모든 절감액을 변경했으나 버튼 (거의 항상 삭제 버튼)을 눌렀을 때 애플 리케이션을 고정시키지 않는 것으로 보입니다. 또한, 데이터베이스가 아직 저장되지 않았기 때문에 삭제할 항목이 없다고 임의로 말합니다. 항목을 찾으라는 요청이 정확하다고 확신합니다. – David
당신은 여전히 그걸 제대로 가지고 있지 않습니다. 불행히도 저녁 7시에 친구가 있어야하는데 6시 43 분이고 집에서 45 분입니다. 나는 또한 코드 스 니펫이 암시하는 것보다 더 많은 일이 일어나고 있다는 느낌을 가지고 있습니다. 현재하고있는 일에 대해 좀 더 게시 할 수 있다면, 오늘 밤 늦게까지하고있는 것과 비슷한 UIManagedDocument 예제를 함께 넣을 수 있는지 알게 될 것입니다. –
다시 한번 고마워, 조디! 더 많은 코드를 표시하기 위해 게시물을 다시 편집했습니다. 희망은 당신이 더 나은 아이디어를 만드는 데 도움이! 내 코드는 게시물의 내용과 매우 흡사합니다. 나는'loadDataIntoDatabase :'의 내용을'dispatch_async (dispatch_get_main_queue(),^{}) '에 넣으려고했지만 아무 것도 변하지 않는 것 같습니다. 어쩌면 나는이 모든 것을 나쁜 방식으로 접근하고있을 것이다 ... 나는 단지 데이터베이스가 한번 데이터로 채워지기를 원한다. 그런 다음 버튼을 누를 때 매개 변수를 업데이트하고, 너무 자주 수정되는 다른 파일에서 매개 변수를 읽는다. 너무 복잡해서는 안된다, 나는 생각한다 ... : S – David