2013-02-14 3 views
5

나는 다음과 같은 코드가 다음 오류 메시지와 함께MagicalRecords는 이미지를 가져 와서 백그라운드 스레드에서 지속됩니까?

2013-02-13 18:55:47.404 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8386a90) → Saving <NSManagedObjectContext (0x8386a90): *** DEFAULT ***> on *** MAIN THREAD *** 
2013-02-13 18:55:47.404 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8386a90) → Save Parents? 1 
2013-02-13 18:55:47.404 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8386a90) → Save Synchronously? 0 
2013-02-13 18:55:47.497 Giordano.iPhone[13956:c07] Image fetched in saveItemFromJson for cid:7218 order_id:10 
2013-02-13 18:55:47.497 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8386a90) → Saving <NSManagedObjectContext (0x8386a90): *** DEFAULT ***> on *** MAIN THREAD *** 
2013-02-13 18:55:47.498 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8386a90) → Save Parents? 1 
2013-02-13 18:55:47.498 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8386a90) → Save Synchronously? 0 
2013-02-13 18:55:47.499 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x8386a90) Context DEFAULT is about to save. Obtaining permanent IDs for new 10 inserted objects 
2013-02-13 18:55:47.501 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) → Saving <NSManagedObjectContext (0x8385aa0): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD *** 
2013-02-13 18:55:47.502 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) → Save Parents? 0 
2013-02-13 18:55:47.502 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) → Save Synchronously? 1 
2013-02-13 18:55:47.502 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x8385aa0) Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 10 inserted objects 
2013-02-13 18:55:47.505 Giordano.iPhone[13956:c07] __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke21(0x8385aa0) → Finished saving: <NSManagedObjectContext (0x8385aa0): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD *** 
2013-02-13 18:55:47.505 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) NO CHANGES IN ** BACKGROUND SAVING (ROOT) ** CONTEXT - NOT SAVING 

:

2013-02-13 18:55:47.511 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) NO CHANGES IN ** BACKGROUND SAVING (ROOT) ** CONTEXT - NOT SAVING 
2013-02-13 18:55:47.512 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) NO CHANGES IN ** BACKGROUND SAVING (ROOT) ** CONTEXT - NOT SAVING 
2013-02-13 18:55:47.512 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) NO CHANGES IN ** BACKGROUND SAVING (ROOT) ** CONTEXT - NOT SAVING 
2013-02-13 18:55:47.512 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) NO CHANGES IN ** BACKGROUND SAVING (ROOT) ** CONTEXT - NOT SAVING 
2013-02-13 18:55:47.513 Giordano.iPhone[13956:c07] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x8385aa0) NO CHANGES IN ** BACKGROUND SAVING (ROOT) ** CONTEXT - NOT SAVING 


2013-02-13 18:55:47.515 Giordano.iPhone[13956:c07] Error: (null) 
2013-02-13 18:55:47.515 Giordano.iPhone[13956:c07] Error: (null) 
2013-02-13 18:55:47.515 Giordano.iPhone[13956:c07] Error: (null) 

I가 피하는하고

dispatch_async(dispatch_get_main_queue(), ^{ 
    NSManagedObjectContext *localContext = [NSManagedObjectContext contextForCurrentThread]; 

    Item *newItem = [Item createInContext:localContext]; 
    newItem.title = NULL_TO_NIL([itemJson valueForKey:@"title"]); 
    newItem.image_url = NULL_TO_NIL([itemJson valueForKey:@"image_url"]); 
    newItem.order_id = @([[self largestOrderId] intValue] + 1); 

    NSURL *url = [NSURL URLWithString:newItem.image_url]; 
    NSData *data = [[NSData alloc] initWithContentsOfURL: url]; 
    if (data == nil) { 
     NSLog(@"Image data is nil from %@", url); 
    } else { 
     NSLog(@"Image fetched in saveItemFromJson for cid:%@ order_id:%@", newItem.cid, newItem.order_id); 
     newItem.image = [UIImage imageWithData:data]; 
    } 

    if (![localContext hasChanges]) { 
     NSLog(@"No local change detected. Quitting"); 
     return; 
    } 

    [localContext saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { 
     if (!success) 
      NSLog(@"Error: %@", [error localizedDescription]); 
     else 
      NSLog(@"Item persisted for cid:%@ order_id:%@", newItem.cid, newItem.order_id); 
    }]; 
}); 

내가 다음을 많이 받고있는 것으로 보인다을 더 이상 사용되지 않으므로 saveInBackgroundWithBlock을 사용하십시오 (문서를 업데이트해야합니까?)

내 코드에 어떤 문제가 있습니까?

UPDATE

우리 팀은 MagicalRecord 지금은 너무 버그 것을 결정했다. MR에서 코드를 CoreData로 완전히 마이그레이션했습니다. 주목 해 주셔서 감사합니다.

+0

주요 목표는 무엇입니까? 덕분에 –

답변

0

MR_saveOnlySelfWithCompletion:을 사용해 보셨습니까?

2

나는 동일한 문제가있었습니다! MR없이 수동으로 컨텍스트를 저장했을 때만 수정되었습니다. 여기

내 솔루션입니다 :

NSManagedObject + MyCategory.h

여기하는 .m

+ (NSManagedObjectContext *)newMergableBackgroundThreadContext { 
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    context.parentContext = [self mainThreadContext]; 
    [context.userInfo setObject:[NSNumber numberWithInteger:VKCoreDataManagedObjectContextIDTempBackground] 
         forKey:@"contextID"]; 
    [context.userInfo setObject:kVKCoreDataManagedObjectContextBackgroundTemp 
         forKey:@"contextDebugName"]; 
    VKDLog(@"* New mergable backround context created! *"); 
    return context; 
} 

+ (void)saveDataInBackgroundWithBlock:(void (^)(NSManagedObjectContext *))saveBlock completion:(void (^)(void))completion { 
    NSManagedObjectContext *tempContext = [self newMergableBackgroundThreadContext]; 
    [tempContext performBlock:^{ 

     if (saveBlock) { 
      saveBlock(tempContext); 
     } 

     if ([tempContext hasChanges]) { 
      [tempContext saveWithCompletion:completion]; 
     } else { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       if (completion) { 
        completion(); 
       } 
      }); 
     } 
    }]; 
} 

- (void)saveWithCompletion:(void(^)(void))completion { 
    [self performBlock:^{ 
     NSError *error = nil; 
     if ([self save:&error]) { 
      NSNumber *contextID = [self.userInfo objectForKey:@"contextID"]; 
      if (contextID.integerValue == VKCoreDataManagedObjectContextIDMainThread) { 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        if (completion) { 
         completion(); 
        } 
       }); 
      } 
      [[self class] logContextSaved:self]; 
      if (self.parentContext) { 
       [self.parentContext saveWithCompletion:completion]; 
      } 
     } else { 
      [VKCoreData handleError:error]; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       if (completion) { 
        completion(); 
       } 
      }); 
     } 
    }]; 
} 

+ (void)saveDataInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))saveBlock 
          completion:(void(^)(void))completion; 

+ (NSManagedObjectContext *)newMergableBackgroundThreadContext; 

- (void)saveWithCompletion:(void(^)(void))completion; 

샘플 사용 : 나는 비슷한했다

[NSManagedObjectContext saveDataInBackgroundWithBlock:^(NSManagedObjectContext *localContext){ 
// do your stuff with local context 
} completion:^{ 
// handle completion, update UI or something 
}]; 
+0

. 우리는 MR도없는 비슷한 것을했습니다. – disappearedng

2

M을 이용한 문제 R 몇 주 전에. 결국 나는 그것을 버리고 모든 것을 스스로하기로 결정했습니다. 당신의 문제에 대한 해결책은 아니지만 그것을 떨어 뜨리는 추론은 건전합니다. 아마도 MR에 대한 실제 출처를 살펴볼 필요가있을 것입니다. 문서의 상당 부분이 올바르지 않으며 상당한 양의 라이브러리는 소스를 읽음으로써 만 학습 할 수 있습니다. MR에서 백그라운드 처리를 시도하는 데 문제가있을 수 있습니다.

코드가 iOS6 + 용인 경우 Master-Main-Child 컨텍스트 설정 만 사용해야합니다. dispatch_async를 사용하는 것도 문제 일 수 있습니다. 코어 데이터가 [NSManagedContext performBlock :] 메서드를 사용하여 스레딩을 관리하게하는 것은 아마 전 세계가 더 안전 할 것입니다.

iOS5 이하를 사용하는 경우 하위 컨텍스트 및 performBlock : 코드가 작동하지 않습니다. 가장 쉬운 해결책은 스레드에서 코어 데이터를 유지하는 것입니다. 새 스레드/블록을 입력하기 전에 코어 데이터에서 필요한 정보를 가져옵니다. 해당 데이터를 블록으로 전달하고 필요한 처리를 수행하십시오. 그런 다음 사전/주체의 주 스레드로 돌아가서 핵심 데이터를 저장하십시오.

또한 이미지를 다운로드하고 코어 데이터에 저장하기 때문에이 문제가 발생했습니다. 지난 몇 주간 내가 물었던 질문에 대한 답을 구할 수 있습니다.나중에 약간의 머리를 잡아 당겨 당신을 저장할 수 있습니다

Can I access the files used for external binary storage in Core Data?

결국 대신 파일의 코어 데이터의 내 자신의 저장 메커니즘을 사용하여 저를 리드하고있는 결국이 문제/솔루션으로 저를 이끌어

:

Files are no longer readable after updating application to newest version

+0

감사합니다. 나는 MR도 나 자신을 떨어 뜨렸다. – disappearedng