你好,歡迎來到IOS教程網

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

Core Data使用(上篇)

編輯:關於IOS

本小節主要講述Core Data相關方面的知識,以及如何使用。

Core Data基礎知識

官方的說法是:Core Data is a schema-driven object graph management and persistence framework.

翻譯過來的意思大概是:Core Data是一個模式驅動的對象圖管理和持久化框架。

好吧,上面的字面意思不是很容易理解,那麼我們從以下幾個方面來幫助那些有其余開發經驗的程序員樹立一些觀念:

  1. Core Data不是一個數據庫,但是他可能使用一個數據庫。默認情況下,Core Data將使用SQLite,但是你可以完全不用關心任何關系型數據庫相關知識,或者SQL語句;
  2. Core Data不是一個類似於Hibernate的對象關系映射框架。Core Data僅僅是一個對象間的關系模型,用戶無需數據庫知識,並且數據也不一定保存在數據庫中;
  3. Core Data允許你去保存模型對象到文件中並且可以在需要的時候取回數據,這一系列操作類似於打包和序列化操作,但是Core Data能夠做的更多;

Core Data能夠做的比較強大的功能包括:

  1. Core Data提供了維護模型對象變化的基礎能力,這樣你可以執行撤銷和重做操作,並且Core Data可以維護對象間的相互關系;
  2. Core Data允許你在給定時間內在內存中保留模型對象的一個子集,這對於嚴苛的iOS內存環境相當重要;
  3. 使用Schema來描述模型對象。你可以在一個圖形化的編輯器中定義你的模型的主要特性,甚至可以包含各個對象間的關系。這樣提供了一個簡單的手段來保證一個基本的健壯性,例如可以設置缺省值和屬性值的驗證;
  4. 允許你維護對象的不想交集合。例如,允許你在一個視圖中對對象進行編輯,但這個內容可能被丟棄,導致另一個視圖中不更新對象;
  5. 對對象的版本管理操作提供支持,這樣可以很方便的將舊版對象升級為新版對象;

Core Data不是一個單獨的類,而是一群需要互相協作的類的集合。整個Core Data的架構圖是比較復雜的:

實例

MyCoreData

  1. 建立一個新的Empty工程,名字叫MyCoreData,工程屬性選擇Core Data和ARC支持;
  2. 在繼續下一步之前,我們了解幾個內容:
    • Managed Object Model,描述了你將在App中使用的Schema。如果你有數據庫背景知識,你可以想象一下數據庫的Schema。這裡的Schema實際上指的是一個對象(或者說實體)的集合。在XCode中,模型被保存在.xcdatamodeld文件中。你可以使用可視化的編輯器來定義實體、屬性、關系等;
    • Persistent Store Coordinator,在iOS中默認使用SQLite存儲持久化數據,當然Core Data提供了存儲不同實體到不同存儲對象的手段。PSC就是對存儲手段進行維護的管理器。當然你完全可以忘記這個對象,因為你基本上不需要和他直接交互;
    • Managed Object Context,這個對象用於管理對象的序列化和反序列化工作,也是在使用Core Data Stack時主要使用的工具;
    • 整理下可以發現,從底層往上的順序分別是:DataStore->Persistent Object Store->Persistent Store Coordinator->Managed Object Context->App;
  3. 基本概念講完了,我們點擊項目生成的.xcdatamodel文件,點擊Add Entity,添加一個實體,名字叫Novel;
  4. 添加屬性,定義如下的三個屬性值:
  5. 創建用戶界面,在File->New中創建一個StoryBoard,然後在Project屬性中設置為這個Story Board;
  6. 在AppDelegate.m文件中,將自動生成的didFinishLaunchingWithOptions方法的實現清空,變為: [cpp] view plaincopy

    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    2. {
    3.     return YES;
    4. }
  7. 在Story Board編輯界面中,添加一個Table View Controller、一個View Controller,設置Table View Controller跳轉到View Controller(注意選擇Segue的Modal,因為後面使用dismissViewController來釋放Details窗口),並且Embed in到Navigator View Controller;
  8. 在Table View Controller中添加一個Button,並且選擇Button的Identifier為Add,使之變成一個加號按鈕;
  9. 選擇Table View的Cell,將其Style修改為Right Detail;
  10. 去那個名為Details的View Controller,先放置一個Navigation Bar到界面上面,然後拖動兩個Button到Navigation Bar上面,並且分別設置對應的Bar Button Item的Identifier屬性為Cancel和Save,如下:
  11. 在Details界面中添加三個text field,並且分別設置他們的placeholder屬性為:name、author、version;
  12. ListView上面的那個加號按鈕在點擊時需要跳轉到Details界面,所以需要在Story Board上選擇這個按鈕,按住Control鍵,拖動到Details這個View之上後釋放鼠標,選擇Segue->Modal;
  13. 在源代碼文件夾中創建一個Object-C類,命名為NovelListViewController,父類選擇UITableViewController;
  14. 在Story Board中,將Table View的Class設置為NovelListViewController;
  15. 同樣,設置Details這個View的Class為新建立的NovelDetailsViewController;
  16. 在NovelDetailsViewController中生成和界面中的TextField對應的控件變量及響應方法: [cpp] view plaincopy

    1. #import <UIKit/UIKit.h>
    2. @interface NovelDetailsViewController : UIViewController
    3. @property (strong, nonatomic) IBOutlet UITextField *tfName;
    4. @property (strong, nonatomic) IBOutlet UITextField *tfAuthor;
    5. @property (strong, nonatomic) IBOutlet UITextField *tfVersion;
    6. - (IBAction)cancel:(id)sender;
    7. - (IBAction)save:(id)sender;
    8. @end
  17. 接下來進入正題,我們將進入操作Core Data的階段。我們將要實現的主要功能包括:在Details頁面中保存數據,在List頁面中將數據取回;
  18. 在NovelDetailsViewController.m中加入代碼: [cpp] view plaincopy

    1. - (NSManagedObjectContext *)managedObjectContext {
    2.     NSManagedObjectContext *context = nil;
    3.     id delegate = [[UIApplication sharedApplication] delegate];
    4.     if ([delegate performSelector:@selector(managedObjectContext)]) {
    5.         context = [delegate managedObjectContext];
    6.     }
    7.     return context;
    8. }
  19. 記得我們當時對工程添加Core Data支持的時候,我們的AppDelegate中自動添加了一個Managed Object Context,我們將使用這個Context來保存或者取回對象;
  20. 我們將兩個按鈕的事件處理方法變為: [cpp] view plaincopy

    1. - (IBAction)cancel:(id)sender {
    2.     [self dismissViewControllerAnimated:YES completion:nil];
    3. }
    4. - (IBAction)save:(id)sender {
    5.     // get Managed Object Context
    6.     NSManagedObjectContext *context = [self managedObjectContext];
    7.     // Create a new managed object
    8.     NSManagedObject *newNovel = [NSEntityDescription insertNewObjectForEntityForName:@"Novel" inManagedObjectContext:context];
    9.     [newNovel setValue:self.tfName.text forKey:@"name"];
    10.     [newNovel setValue:self.tfAuthor.text forKey:@"author"];
    11.     [newNovel setValue:self.tfVersion.text forKey:@"version"];
    12.     NSError *error = nil;
    13.     // Save the object to persistent store
    14.     if (![context save:&error]) {
    15.         NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    16.     }
    17.     [self dismissViewControllerAnimated:YES completion:nil];
    18. }

    當點擊Cancel按鈕的時候,我們使用一個動畫方式將Details窗口關閉掉。
    當點擊Save按鈕的時候,我們首先獲取Context,然後創建一個新的Managed Object,設置novel的屬性,接著調用context的save來存儲數據,最後關閉界面。

  21. 現在我們看如何獲取列表。我們在TableViewController中添加一個數組用來保存Novel的列表: [cpp] view plaincopy

    1. #import <UIKit/UIKit.h>
    2. @interface NovelListViewController : UITableViewController
    3. @property(strong, nonatomic) NSMutableArray *novelList;
    4. @end
  22. 同樣對於List頁面需要添加獲取Context和加載時獲取數組元素列表接口: [cpp] view plaincopy

    1. @implementation NovelListViewController
    2. @synthesize novelList;
    3. - (NSManagedObjectContext *)managedObjectContext
    4. {
    5.     NSManagedObjectContext *context = nil;
    6.     id delegate = [[UIApplication sharedApplication] delegate];
    7.     if ([delegate performSelector:@selector(managedObjectContext)]) {
    8.         context = [delegate managedObjectContext];
    9.     }
    10.     return context;
    11. }
    12. - (void)viewDidAppear:(BOOL)animated
    13. {
    14.     [super viewDidAppear:animated];
    15.     // Fetch the devices from persistent data store
    16.     NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    17.     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Novel"];
    18.     self.novelList = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
    19.     [self.tableView reloadData];
    20. }
  23. 接下來改造List界面的表格顯示模塊: [cpp] view plaincopy

    1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    2. {
    3. #warning Potentially incomplete method implementation.
    4.     // Return the number of sections.
    5.     return 1;
    6. }
    7. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    8. {
    9. #warning Incomplete method implementation.
    10.     // Return the number of rows in the section.
    11.     return self.novelList.count;
    12. }
    13. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    14. {
    15.     static NSString *CellIdentifier = @"Cell";
    16.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    17.     // Configure the cell...
    18.     NSManagedObject *device = [self.novelList objectAtIndex:indexPath.row];
    19.     [cell.textLabel setText:[NSString stringWithFormat:@"%@ %@", [device valueForKey:@"name"], [device valueForKey:@"version"]]];
    20.     [cell.detailTextLabel setText:[device valueForKey:@"author"]];
    21.     return cell;
    22. }

    注意在Story Board中設置Table View Cell的Identifier屬性值為Cell,與代碼中的保持一致。

  24. 至此,程序功能全部完成,查看發現數據能夠正常保存,但我們沒有寫一行和數據庫相關的代碼。

 

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