2013-10-11 90 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; 
     }]; 
    } 
}