閱讀394 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Core Data淺談係列之三 : 了解NSManagedObject和NSPredicate

上一篇文章用實際代碼演示了Core Data應用中基本的增刪改查操作,使用的是NSManagedObject對象,利用KVC來修改、獲取對象的屬性值。
除此之外,我們還可以創建與Player、Team相對應的具體的NSManagedObject子類,如下圖:



Xcode會為我們生成子類的代碼,如Player的接口聲明和實現(汗,從Xcode複製代碼到Evernote,有些空格會被省略):
@interface Player : NSManagedObject

@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * name;

@end


@implementation Player

@dynamic age;
@dynamic name;

@end
這裏的屬性age和name並沒有使用@synthesize進行合成,而是使用@dynamic,表明該屬性的訪問函數並非由該類來提供。
有了自定義子類後,我們就可以更簡潔地操作對象,比如對Team的讀寫可以改成:
    NSArray *teamArray = [self fetchTeamList];
    if (teamArray) {
        for (Team *teamObject in teamArray) {
            NSLog(@"Team info : %@, %@\n", teamObject.name, teamObject.city);
        }
    }
以及 :
    Team *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    teamObject.name = teamName;
    teamObject.city = teamCity;
然後再執行一遍程序。這時候,發現程序輸出重複的球隊信息,因為我們創建了兩次同樣的數據。但實際上一個聯盟不應該存在相同名稱的兩支球隊,所以我們應該在插入數據的時候進行驗證(這種情況下,創建Team的函數也根據含義而改名):
- (BOOL)insertTeamWithName:(NSString *)teamName city:(NSString *)teamCity
{
    if (!teamName || !teamCity) {
        return NO;
    }
    
    Team *teamObject = [self getTeamInfoByName:teamName];
    if (nil == teamObject) {
        teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    }
    
    teamObject.name = teamName;
    teamObject.city = teamCity;
    
    return YES;
}

- (Team *)getTeamInfoByName:(NSString *)teamName
{
    Team *teamObject = nil;
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    
    NSEntityDescription *teamEntity = [NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:teamEntity];
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", teamName];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setFetchLimit:1];
    
    NSError *error = NULL;
    NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (error) {
        NSLog(@"Error : %@\n", [error localizedDescription]);
    }
    
    if (array && [array count] > 0) {
        teamObject = [array objectAtIndex:0];
    }
    
    [fetchRequest release], fetchRequest = nil;
    
    return teamObject;
}
把已經安裝的App刪除,然後重新運行下程序,可以看到不管運行多少次,都隻會有Heat和Lakers兩支球隊的信息輸出。

這是我們顯式創建新的NSManagedObject實例時所采取的去重方案,使用NSPredicate進行條件查詢,如果已經存在指定名稱的球隊就不再重複創建。
如果是在關聯屬性時這麼寫代碼,比如為一支球隊添加多名球員,會顯得有點冗餘。對於這種情況,可以進行屬性驗證,這會和NSPredicate的使用放在後麵進一步討論。

Brief Talk About Core Data Series, Part 3 : Understanding NSManagedObject & NSPredicate

Jason Lee @ Hangzhou

最後更新:2017-04-04 07:03:38

  上一篇:go POJ 1595 素數篩法
  下一篇:go POJ 2142 擴展歐幾裏得