你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> Core Data使用(下篇)

Core Data使用(下篇)

編輯:關於IOS

本篇主要講述一些細枝末節的知識點。

建模

屬性和關系

在XCode中,建模時就可以添加屬性和標識實體間的相互關系。具體參見下圖,下面還有對應說明:

  1. Entities中列舉了實體的列表;
  2. 每個Entity的屬性列表在Attributes中,注意Attributes可以多選之後在右邊一起改屬性類型;
  3. 通過添加關系可以標識出兩種不同類型的Entity之間的相互聯系;
  4. 每個Relationship都是可以編輯的,主要側重於一對一還是多對一的關系描述;在我們這個例子中,我們在Employer中設置一對一的關系,然後在Company中選擇"To-Many Relationship"選項,使得Company與Employer變成一對多的關系;
  5. 編輯完相互關系後,在Inverse中設置一下,使兩者的關系變成真正的關聯關系,而不是孤立的聯系(這個可以選擇Editor Style為table看到兩者區別),到這裡是不是和Hibernate有點類似了Core Data使用(下篇)

創建NSManagedObject類的子類

好處——類型校驗

創建NSManagedObject類的子類的對象的好處是你可以不用如下的代碼(很明顯如下的代碼是沒有類型校驗的):

[cpp] view plaincopy

  1. NSManagedObject *event = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:managedObjectContext];
  2. [event setValue:[NSDate date] forKey:@"creationDate"];

步驟

  1. 選中.xcdatamodeld這個模型文件;
  2. 選中一個實體;
  3. 從菜單中選擇Editor->Create NSManagedObject class,可以創建需要的子類;

取回數據

注意fetch data的時候實際上可以直接使用code snippet,如下:

使用斷言

使用斷言可以用來篩選我們取出的數據,所以我們的代碼可能是這樣,同樣可以使用code snippet:

[cpp] view plaincopy

  1. -(void)loadData
  2. {
  3.     // Create the Request
  4.     NSFetchRequest *request = [[NSFetchRequest alloc] init];
  5.     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
  6.     [request setEntity:entity];
  7.     // Set the Sort Descriptor
  8.     NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
  9.     NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
  10.     [request setSortDescriptors:sortDescriptors];
  11.     // Create Predicate
  12.     // equal
  13. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description == 'Tom's birthday'"];
  14. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description == [c]'tom's birthday'"];
  15.     // like
  16. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description LIKE 'Tom*'"];
  17. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description LIKE [cd]'Tom*'"];
  18. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description LIKE '*om*'"];
  19.     // begins
  20. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description BEGINSWITH 'TOM'"];
  21.     // date
  22. //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"createDate < %@", [NSDate date]];
  23.     // and
  24.     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"description BEGINSWITH 'TOM' AND createDate < %@", [NSDate date]];
  25.     [request setPredicate:predicate];
  26.     // Execute the Request
  27.     NSError *error = nil;
  28.     NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
  29.     if (mutableFetchResults == nil) {
  30.         // Handle the error.
  31.         NSLog(@"error loading data");
  32.     }
  33.     // Finish Up
  34.     [self setEventsArray:mutableFetchResults];
  35. }

創建帶斷言的fetching request templete

創建模板的好處是XCode本身提供了一個編輯器,這樣就不需要我們自己編寫這部分斷言代碼,而是可以使用圖形化的方式編輯我們的條件,而且便於我們管理這部分代碼。

  1. 我們選擇模型文件,然後去菜單,選擇Editor->Add Fetch Request:
  2. 進入之後的頁面中我們可以編輯我們的條件,並且可以切換圖形和代碼方式查看:
  3. 編輯完條件後,我們的代碼變更為: [cpp] view plaincopy

    1. // Create Fetch Request
    2. NSFetchRequest *fetchRequest = [[self managedObjectModel] fetchRequestTemplateForName:@"EssentialCourses"];
    3. // Create Sort Descriptor
    4. NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"releaseDate" ascending:YES];
    5. NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sort, nil];
    6. [fetchRequest setSortDescriptors:sortDescriptors];
    7. NSError *error = nil;
    8. NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    9. if (fetchedObjects == nil) {
    10.     NSLog(@"Problem! %@",error);
    11. }
    12. for (Course *c in fetchedObjects) {
    13.     NSLog(@"Course: %@ by author: %@", c.title, c.author);
    14. }
  4. 運行,查看效果。

版本管理

數據不能兼容

對於數據不能兼容的情況,我們在AppDelegate中做如下處理:

[cpp] view plaincopy

  1. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
  2. {
  3.     if (_persistentStoreCoordinator != nil) {
  4.         return _persistentStoreCoordinator;
  5.     }
  6.     NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataCourse.sqlite"];
  7.     NSError *error = nil;
  8.     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
  9.     if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
  10.         // delete record
  11.         [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
  12.         NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  13.         abort();
  14.     }
  15.     return _persistentStoreCoordinator;
  16. }

注意其中的removeItemAtURL。

向前兼容

為了數據能夠向前兼容老版本,你需要做如下工作:

  1. 創建實體的新版本;
  2. 新實體創建後會出現如下圖的對應model文件:
  3. 去編輯新的實體;
  4. 選中.cxdatemodelId,在右邊的屬性中選擇激活的模型版本;
  5. 修改代碼,注意新增加的options: [cpp] view plaincopy

    1. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
    2. {
    3.     if (_persistentStoreCoordinator != nil) {
    4.         return _persistentStoreCoordinator;
    5.     }
    6.     NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataCourse.sqlite"];
    7.     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption, nil];
    8.     NSError *error = nil;
    9.     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    10.     if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
    11.         NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    12.         abort();
    13.     }
    14.     return _persistentStoreCoordinator;
    15. }
  6. 這裡還是描述的簡單情況,實際的版本管理和數據合並更加復雜,您可能需要參考:https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/CoreDataVersioning/Articles/Introduction.html

尾聲

到這裡基本上Core Data相關的功能已經介紹完了,整體上看下來Core Data的學習曲線還是蠻陡峭的,但是基本的使用非常簡單,建議大家在工作中逐步摸索。

下面是我學習的一個完整小例子供大家參考:下載地址。

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved