0

핵심 데이터 응용 프로그램에서 내 컨트롤러에서 내 모델로 일부 코드를 이동하는 중입니다.NSManagedObject 전달

정기적으로 만드는 특정 가져 오기 요청에 대해 NSManagedObjectID를 반환하는 메서드를 작성했습니다.

+ (NSManagedObjectID*)teamProjectWithProjectId:(NSNumber *)projectId inContext:(NSManagedObjectContext*)context 
{ 
    NSFetchRequest *teamRequest = [[NSFetchRequest alloc] initWithEntityName:@"TeamProject"]; 
    NSPredicate *teamPredicate = [NSPredicate predicateWithFormat:@"teamProjectId == %@",projectId]; 
    teamRequest.predicate = teamPredicate; 
    TeamProject *teamProject = [[context executeFetchRequest:teamRequest error:nil] lastObject]; 
    if (teamProject) 
    { 
     return [teamProject objectID]; 
    } 
    else 
    { 
     return nil; 
    } 
    return nil; 
} 

그리고 지금 모든 곳에서 나는이 작업을 수행하는 방법 사용할 필요가 : 이제이 너무 나쁘지 않다 작동하고 NSManagedObjectID 스레드가하면서, NSManagedObject 스레드 안전되지 않는 존중

NSManagedObjectID *teamProjectMoId = [TeamProject teamProjectWithProjectId:projectID]; 
TeamProject *currentProject = nil; 
if (teamProjectMoId) 
{ 
    currentProject = (TeamProject*)[self.managedObjectContext objectWithID:teamProjectMoId]; 
} 

을 안전한. 그리고 내 컨트롤러 클래스에서 꽤 많은 코드를 내 모델 범주로 옮길 수있어서 기쁩니다.

그러나 이것은 충분하지 않습니다. 정말 스레드 안전성을 존중하는 방식으로 단 한 줄의 코드로 NSManagedObject에 액세스하려고합니다. 내 이상은 다음과 같이 쓸 수있는 것입니다 :

TeamProject *currentProject = [TeamProject magicalMethodThatHandlesThreadSafety]; 

이것도 가능합니까? 아니면 누구나 NSManagedObject의 깨끗한 접근 메서드를 작성하기위한 전략이 있습니까?

답변

1

백그라운드에서 룩업해야하는 모든 곳에서 임시 MOC를 만들 수 있습니다. 이것은 확실히 실마리가 있으며 ID를 사용하는 것보다 빠릅니다 (실제로는 MOC를 빠르게 만드는 것이 빠르기 때문에 실제로 빠릅니다). 그 일의

한 가지 방법은 NSPrivateQueueConcurrencyType 동시성 유형을 지정 기본 컨텍스트에 아이를 통해입니다 :

+ (TeamProject*)teamProjectWithProjectId:(NSNumber *)projectId inContext:(NSManagedObjectContext*)context 
{ 

    NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    temporaryContext.parentContext = context; 

    NSFetchRequest *teamRequest = [[NSFetchRequest alloc] initWithEntityName:@"TeamProject"]; 
    NSPredicate *teamPredicate = [NSPredicate predicateWithFormat:@"teamProjectId == %@",projectId]; 
    teamRequest.predicate = teamPredicate; 
    TeamProject *teamProject = [[temporaryContext executeFetchRequest:teamRequest error:nil] lastObject]; 

    return teamProject; 
} 

도 더 시나리오와 솔루션에 대한 this post에서보세요.

편집 :

일을 명확하게하기 위해, 위의 방법이 반환 된 MO를 사용하는 것과 동일한 스레드에서 호출하기위한 것입니다. 위의 접근 방식의 "확장"일뿐입니다. 즉, 로컬에서 생성 된 MOC를 사용하여 가져 오기 작업을 래핑하여 해당 스레드에 대해 비공개이므로 안전하게 사용할 수 있습니다.

즉, 위의 메서드를 모든 스레드에서 호출하고 반환 된 MO를 동일한 스레드에서 안전하게 사용할 수 있습니다. 자식 MOC를 사용하는 속임수는 임시 MOC의 생성을 통해 임의의 스레드에서 가져 오기를 수행 할 수있게합니다.

다른 스레드에서 생성 된 MOC를 참조하여 현재 스레드에서 하위 MOC를 만드는 것이 안전합니다.

한 스레드에서 다른 스레드로 관리 객체를 전달하는 것이 허용되지 않는 것은 사실입니다.

+0

그 게시물은 정확히 내 스택 설정 방법입니다. 감사. NSManagedObject를 전달하는 것과 관련된 스레드 문제가 NSManagedObjectContexts와 직접 관련되어 있기 때문에이 작업이 가능합니까? – hatunike

+0

제발 내 편집을 참조하십시오. 나는 그 방법이 어떻게 사용되어야하는지 명확히하려고 노력했다. – sergio

+0

매우 명확합니다. 고맙습니다. – hatunike