2011-02-11 62 views
13

核心數據驅動應用程序的常見情況是從後備存儲中獲取唯一對象。如果具有某個唯一屬性的對象存在,則返回該對象,如果它沒有返回新創建的對象。我發現自己一遍又一遍地寫同樣的東西,所以我用一種方便的方法來包裝它。但是這似乎很瑣碎,我是否在這裏重新發明輪子?有沒有更簡單的開箱即用的方法來實現這一目標?查找或創建獨特的核心數據實體

乾杯,
EP

+(id)uniqueEntityfForName:(NSString *)name 
       withValue:(id)value 
        forKey:(NSString *)key 
    inManagedObjectContext:(NSManagedObjectContext *)context { 

    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];  
    request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:context]; 
    request.predicate = [NSPredicate predicateWithFormat:[key stringByAppendingString:@" == %@"], value]; 
    NSArray *result = [context executeFetchRequest:request error:nil]; 

    id entity = [result lastObject]; 
    if (entity == nil) { 
     entity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context]; 
     [entity setValue:value forKey:key]; 
    } else { 
     entity = [result lastObject]; 
    } 

    return entity; 
} 

我使用此方法是這樣的:

​​
+1

看起來有效。當用於非GC項目時可能會發生內存泄漏,因爲您沒有發佈'請求' – diederikh 2011-02-11 21:43:18

+0

完全!我仍然需要與內存釋放保持一致。更新代碼。 – epologee 2011-02-11 21:50:08

+0

非常標準。我的核心數據實體有許多方法,如[aStudent enrollmentForId:(long long)idValue createIfMissing:YES]。我還想插入mogenerator http://rentzsch.github.com/mogenerator/,它可以消除Core Data中的很多痛苦。除此之外,它爲數據模型中定義的每個提取請求生成一個工廠方法。因此,製作一個類似於thingies的獲取謂詞:「thingyId == $ forThingyId」會產生一個匹配的類方法:+(NSArray *)fetchThingies :(託管對象上下文*)moc forThingyId:(id)thingyId,你已經寫在那裏。 – rgeorge 2011-02-11 22:02:10

回答

3

漂亮的標準。我的核心數據實體有很多方法,如[aStudent enrollmentForId:(long long)idValue createIfMissing:YES]

我還想插入mogenerator,這可以消除Core Data中的很多痛苦。除此之外,它爲數據模型中定義的每個提取請求生成一個工廠方法。所以,製作模型等,例如取謂詞,

一樣的東西:thingyId == $forThingyId

產生一個匹配類方法:

+(NSArray *)fetchThingies:(NSManagedObjectContext *)moc forThingyId:(id)thingyId 

...這確實上半年你在那裏寫的東西。像

-(Thingy*)thingyForIdValue:(long long)thingyId 

一個包裝是那麼瑣碎寫的,在任何類握着你的managedObjectContext(例如,「父」實體,或應用程序的委託,或什麼的。)

2

更靈活的解決方案是使用Blocks在比較兩個列表時讓調用者處理3種情況。

  1. 相互匹配的
  2. 主機無與倫比的套
  3. 地方無法比擬的套

因此,沒有必要在一個同步的方式或增加的數據存儲在插入時創建類似的功能。

typedef void (^objectOperationBlock)(NSManagedObjectContext *context, 
           NSDictionary *hostObjectData, 
           NSManagedObject *localManagedObject); 

- (void) insertUniquely:(NSArray *)rawDataArray 
       entity:(NSString *)entity 
      matchedBlock:(objectOperationBlock)matchedOperation 
    hostUnmatchedBlock:(objectOperationBlock)hostUnmatchedOperation 
    localUnmatchedBlock:(objectOperationBlock)localUnmatchedOperation 
        error:(NSError **)outError; 

完全實施可以在這裏找到:http://emplementation.blogspot.com/2011/12/importing-data-into-core-data-while.html