2013-10-11 4 views
2

NSManagedObjectContextObjectsDidChangeNotification 핸들러에서 관리 객체의 속성을 변경하는 것이 핸들러를 다시 시작하지 않고 가능합니까? 서버에서 데이터를 가져오고 RestKit은 데이터를 핵심 데이터에 매핑합니다. 데이터베이스에 데이터가 도착한 후에 일부 속성을 변경해야합니다. 도움 주셔서 감사합니다.핵심 데이터 : NSManagedObjectContextObjectsDidChangeNotification의 객체 변경

편집 : 이것은 내 코드입니다. handleDidChangeNotification 방법은주기에 호출됩니다

- (void)addMyObserver 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(handleDidChangeNotification:) 
               name:NSManagedObjectContextObjectsDidChangeNotification 
               object:self.objectManager.managedObjectStore.mainQueueManagedObjectContext]; 
} 

- (void)handleDidChangeNotification:(NSNotification *)notification 
{ 
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey]; 
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey]; 
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey]; 

    // modifiedObjects with store entity: 
    NSSet *modifiedObjects = [updatedObjects setByAddingObjectsFromSet:insertedObjects]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF isKindOfClass: %@", [MyStore class]]; 
    NSSet *modifiedStoreObjects = [modifiedObjects filteredSetUsingPredicate:predicate]; 

    if (modifiedStoreObjects.count > 0) 
    { 
     [modifiedStoreObjects enumerateObjectsUsingBlock:^(MyStore *store, BOOL *stop) 
     { 
      store.distanceValue = 1000; 
     }]; 
    } 
} 
+0

가져 오기에 별도 MOC 사용을 고려 했습니까? 그렇게하면이 변화를 만들기 위해 그 맥락을 관찰 할 수 있습니다. – paulbailey

답변

3

당신이 원시적 인 접근 방법, 예를 사용할 수 있으며, 변경 알림을 발사하지 않고 코어 데이터 객체를 수정하려면

[store setPrimitiveValue:@1000 forKey:@"distanceValue"]; 

,

(. 객체 값이 스칼라 값이 작동하지 않습니다, 여기에 필요합니다) 그러나 원하지 않는 부작용이없는 경우 당신은 신중하게 고려해야합니다 다른 청취자 것 또한 때문에 변경된 값에 대해서는이 통지되지 않습니다.

또 다른 가능한 해결책은 속성을 전혀 변경해야하는지 확인하고 이며 필요한 경우에만 수정하는 것입니다.

+0

나는 이것에 대해 들었지만,이 경우에는 권장되지 않으며 부작용이있을 수 있다고 생각합니다. 내 데이터 요청의 응답을 검색 한 후 수동으로 거리 업데이트를 수행 할 것이라고 생각합니다. 귀하의 답변에 감사드립니다. –

+0

이 작업이 취소 되나요? – malhal

+0

@malhal : 잘 모르겠습니다. –

0

예제 서브 클래스를 표시하는 방법 NSManagedObject. YourPropertyName는 -

@implementation YourPropertyName 

@dynamic stringValueOfYourProperty;//for example 

-(void)setStringValueOfYourProperty:(NSString *) _stringValueOfYourProperty 
{ 
    [self willChangeValueForKey:@"stringValueOfYourProperty"]; 
    [self setPrimitiveValue: _stringValueOfYourProperty forKey:@"stringValueOfYourProperty"]; 
    [self didChangeValueForKey:@"stringValueOfYourProperty"]; 
} 

그럼 그냥 사용 setStringValueOfYourProperty 어디서나 코드에서 클래스입니다.

+0

그러나'didChangeValueForKey'는 OP가 피하려고했던 변경 알림을 다시 발생시킵니다. –

+0

'didChangeValueForKey'가 없으면 응용 프로그램이 다중 사용자 인 경우 부작용을 얻을 수 없습니까? –

1

다음 코드는 테스트되지 않은 내 머리 꼭대기에서 벗어났습니다.하지만 이것이 내가 어떻게 될지 알려주는 것입니다.

@interface MyStoreCoordinator() { 
    bool _changingValue; 
} 
@end 

@implementation MyStoreCoordinator 

- (void)addMyObserver 
{ 
    _changingValue = NO; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(handleDidChangeNotification:) 
               name:NSManagedObjectContextObjectsDidChangeNotification 
               object:self.objectManager.managedObjectStore.mainQueueManagedObjectContext]; 
} 

- (void)handleDidChangeNotification:(NSNotification *)notification 
{ 
    if (_changingValue) 
    { 
     return; 
    } 

    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey]; 
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey]; 
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey]; 

    // modifiedObjects with store entity: 
    NSSet *modifiedObjects = [updatedObjects setByAddingObjectsFromSet:insertedObjects]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF isKindOfClass: %@", [MyStore class]]; 
    NSSet *modifiedStoreObjects = [modifiedObjects filteredSetUsingPredicate:predicate]; 

    if (modifiedStoreObjects.count > 0) 
    { 
     [modifiedStoreObjects enumerateObjectsUsingBlock:^(MyStore *store, BOOL *stop) 
     { 
      _changingValue = YES; 
      store.distanceValue = 1000; 
      _changingValue = NO; 
     }]; 
    } 
} 
관련 문제