2014-04-28 3 views
5

내 프로젝트의 RestKit 및 Core Data 사용 형식을 가장 잘 나타내려고합니다. 내가 일하는 몇 가지가 있지만, 나는 그들이 가난하게 구현되어 잠재적으로 스레드가 안전하지 않은 느낌을 가지고 ... 나는 내 데이터 전송, 스토리지 등을 관리하는 객체를 가지고있다. restkit을 설정합니다. RKObjectManager에 사용하는 인스턴스 변수가 있는데,이 셋업 함수에서 objectStore를 만들고, 모든 속성 매핑을 설정하고, 영구 저장소를 만드는 등의 작업을합니다. 모든 일반 restkit 설치 코드를 만듭니다. 이 함수 밖에서이 객체에 사용할 수있는 것은 _objectManager 인스턴스 변수뿐입니다.이 변수는 NSFetchRequests 등에 사용했습니다.RestKit 및 Managed Object Contexts

제대로 구현하고, 관리되는 개체를 가져오고, 관리되는 개체의 절감 된 변경 사항을 확인하고 싶습니다.

내가 객체에 속성을 업데이트하려면

, 내가이 일을 봤는데 :

object.whatever = @"something here"; 

NSError *error; 
if (![object.managedObjectContext save:&error]) { 
    // log the error here 
} 

이 객체에 속성을 저장/업데이트 할 수있는 적절한 방법이 있나요? 객체의 관리 객체 컨텍스트에 직접 액세스하면 코드의 어느 지점에서든 직접 저장됩니까? 아니면 배경/전경에서만 수행해야하는 작업입니까? 현재의 구현은 백그라운드와 포 그라운드 모두에서 호출 될 가능성이 있으며이를 수용 할 수 있는지 확인하고자합니다.

NSManagedObjectContext *managedObjectContext = // I DONT KNOW WHAT TO PUT HERE! // 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates]; 
    [fetchRequest setPredicate:compoundPredicate]; 

    NSError *error; 
    NSArray *fetchedRecords = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    if (error) { 
     // log error 
    } 

    // if we were given a sort descriptor, sort the array appropriately 
    if (sortDescriptor) { 
     fetchedRecords = [fetchedRecords sortedArrayUsingDescriptors:@[sortDescriptor]]; 
    } 

    return fetchedRecords; 

내 문제는 여기에 있습니다 : 내가 객체를 가져 오기 할 때 재사용 할 수 있도록

, 나는 엔티티 이름을 사용하는 함수, 술어의 배열 및 매개 변수로 정렬 설명을 썼다 올바른 관리 객체 컨텍스트 생성/액세스. 어떻게해야합니까? 이전에 만든 RKObjectManager의 일부 속성에 액세스 할 수 있습니까? 예 :

_objectManager.managedObjectStore.mainQueueManagedObjectContext 

또는 스레드가 안전하지 않은 스레드입니까? 올바른 관리 대상 객체 컨텍스트를 사용하고 있으며 스레드로부터 안전한지 확인하기 위해 수행 할 수있는 작업은 무엇입니까? 내가 사용하던 :

_objectManager.managedObjectStore.persistentStoreManagedObjectContext 

하지만 난이 확실히 가장 좋은 방법이고 스레드 안전하지 않은 들었다, 그래서 가장 좋은 방법을 결정하기 위해 노력하고있어.

EDIT - 객체를 가져올 때마다이 함수를 호출하여 컨텍스트를 가져올 수 있습니다. 대신이의 절약을 위해

- (NSManagedObjectContext *)getManagedObjectContext { 
    if ([NSThread isMainThread]) { 
     return _objectManager.managedObjectStore.mainQueueManagedObjectContext; 
    } 
    else { 
     return [_objectManager.managedObjectStore newChildManagedObjectContextWithConcurrencyType:NSPrivateQueueConcurrencyType tracksChanges:YES]; 
    } 
} 

답변

5

:

if (![object.managedObjectContext save:&error]) { 

당신이 수행해야합니다

if (![object.managedObjectContext saveToPersistentStore:&error]) { 

때문에 변경 사항이 바로 디스크에있는 저장소에 체인까지 지속됩니다. 관리 대상 객체를 생성/가져온 스레드에서만이 작업을 수행해야합니다. 따라서 MOC의 스레드 소유권이 유지됩니다.

전경/배경은 각 스레드에서 MOC를 사용하는만큼 중요하지 않습니다. MOC 스레드 소유권이 존중되면 괜찮을 것입니다.

동일한 것이 페치에 적용됩니다. UI 업데이트의 경우 기본 스레드와 mainQueueManagedObjectContext을 사용해야합니다. persistentStoreManagedObjectContext을 직접 사용하면 안됩니다.임의의 백그라운드 스레드의 경우 관리 객체 저장소에 새 자식 관리 객체 컨텍스트를 만들고이를 사용하도록 요청해야합니다.

+0

매우 도움이되었습니다. 내 주요한 문제는이 함수가 어떤 스레드를 실행 중인지 모르기 때문에 매우 일반적인 함수라는 것이다. mainQueueManagedObjectContext를 사용할지 또는 새 하위 컨텍스트를 만들지 여부를 알 수 있도록 이것을 판별하는 간단한 방법이 있습니까? – Mike

+1

'[NSThread isMainThread]',하지만 몇개의 배경 스레드가 있는지 찾을 수는 없습니다. 때로는'threadDictionary'를 사용하여 이런 종류의 정보를 저장할 수 있습니다 ... – Wain

+0

그 요구 사항을 만족시키는 것으로 위의 편집을 추가했습니다. 그 간단한 변화가 괜찮은지 알려주세요. – Mike