深刻淺出 Cocoa 之 Core Data(3)- 使用綁定

深刻淺出 Cocoa 之 Core Data(3)- 使用綁定app

羅朝輝(http://blog.csdn.net/kesalin)框架

CC 許可,轉載請註明出處oop

前面講解了 Core Data 的框架,並徹底手動編寫代碼演示了 Core Data 的運做過程。下面咱們來演示如何結合 XCode 強大的可視化編輯以及 Cocoa 鍵值編碼,綁定機制來使用 Core Data。有了上面提到的哪些利器,在這個示例中,咱們無需編寫 NSManagedObjectModel 代碼,也無需編寫 NSManagedObjectContext,工程模版在背後爲咱們作了這些事情。

今天要完成的這個示例,有兩個 Entity:StudentEntity 與 ClassEntity,各自有一個名爲 name 的 Attribute。其中 StudentEntity 經過一個名爲 inClass 的 relationship 與 ClassEntity關聯,而 ClassEntity 也有一個名爲 students 的 relationship 與 StudentEntity 關聯,這是一個一對多的關係。此外 ClassEntity 還有一個名爲 monitor 的 relationship 關聯到 StudentEntity,表示該班的班長。編碼

代碼下載:點此下載

最終的效果圖以下:atom

下面咱們一步一步來完成這個示例:
1,建立工程:
建立一個 Cocoa Application,工程名爲:MacCoreData,並勾選 Create Document-Based Application 和 Use Core Data,在這裏要用到 Core Data 和 Document 工程模版,以簡化代碼的編寫。spa

2,分類文件:
在 MacCoreData 下新建 Src 和 Res 兩個 Group,並將 MyDocument.h 和 MyDocument 拖到 Src 下,將其餘 xib 和 xcdatamodeld 拖到 Res 中。將文件分類是個好習慣,尤爲是對大項目來講。後面請自覺將文件分類~~.net

3,建立 Entity:
在工程中,咱們能夠看到名爲 MyDocument.xcdatamodeld 的文件,其後綴代表這是一個 core data model文件,框架就是讀取該模型文件生成模型的。下面咱們選中這個文件,向其中添加兩個實體。點擊下方的 Add Entity 增長兩個新 Entity: ClassEntity 和 StudentEntity。指針

向 StudentEntity 中添加名爲 name 的 string 類型的 Attribute,並設置其 Default Value 爲學生甲,去除 Optional 前勾選狀態;
向 ClassEntity 中添加名爲 name 的 string 類型的 Attribute,並設置其 Default Value 爲XX班,去除 Optional 前勾選狀態;
選項 Optional 是表示該  Attribute 可選與否的,在這裏 name 都是必須的。對象

 

向 StudentEntity 中添加名爲 inClass 指向 ClassEntity 的 Relationship,其 Inverse 欄要等 ClassEntity 添加了反向關係才能選擇,後面回提到;
向 ClassEntity 中添加名爲 students 指向 StudentEntity 的 Relationship,其 Inverse 欄選擇 inClass,代表這是一個雙向關係,勾選 To-Many Relationship,由於一個班級能夠有多名學生,這是一對多關係。設定以後,咱們能夠能夠將 StudentEntity 的 inClass 關係的 Inverse 設置爲 students了。
再向 ClassEntity 中添加名爲 monitor 指向 StudentEntity 的 Relationship,表示該班的班長。blog

4,生成 NSManagedObject 類:
選中 StudentEntity,而後點擊菜單 File-> New -> New file…,添加 Core Data -> NSManagerObject subclass, XCode 就會自動爲咱們生成 StudentEntity.h 和 StudentEntity.m 文件,記得將這兩個文件拖放到 Src Group 下。下面咱們來看看這兩個文件中有什麼內容:
StudentEntity.h

 

  1. #import <Foundation/Foundation.h>  
  2. #import <CoreData/CoreData.h>  
  3.   
  4. @class ClassEntity;  
  5.   
  6. @interface StudentEntity : NSManagedObject {  
  7. @private  
  8. }  
  9. @property (nonatomic, retain) NSString * name;  
  10. @property (nonatomic, retain) ClassEntity * inClass;  
  11.   
  12. @end  

 

 

StudentEntity.m

  1. #import "StudentEntity.h"  
  2. #import "ClassEntity.h"  
  3.   
  4. @implementation StudentEntity  
  5. @dynamic name;  
  6. @dynamic inClass;  
  7.   
  8. @end  


在前面手動代碼的示例中,咱們是本身編寫 Run NSManagedObject的代碼,而如今,XCode 已經根據模型文件的描述,自動爲咱們生成了,方便吧。有時候自動生成的代碼不必定知足咱們的須要,咱們就得對代碼進行修改,好比對 ClassEntity 來講,班長只能是其 students 中的一員,若是咱們在 students 中移除了班長那個學生,那麼該班級的班長就應該置空。

選中 ClassEntity,重複上面的步驟,自動生成 ClassEntity.h 和 ClassEntity.m,下面咱們根據需求來修改 ClassEntity.m。
在 - (void)removeStudentsObject:(StudentEntity *)value 的開頭添加以下代碼:

  1. if (value == [self monitor])  
  2.     [self setMonitor:nil];  


在 - (void)removeStudents:(NSSet *)value 的開頭添加以下代碼:

  1. if ([value containsObject:[self monitor]])  
  2.     [self setMonitor:nil];  


這樣當咱們在 students 中刪除一個學生時,就會檢測該學生是否是班長,若是是,就將該班的班長置空。

 

5,下面來生成 UI 界面:
在這裏,咱們是經過切換 view 的方法來顯現學生與班級兩個界面,所以咱們須要主界面,班級以及學生共三個界面。

向 MyDocument.xib 中添加以下一個 popup button 和一個 NSBox。並刪除 popup 控件中的 menu item,由於咱們要經過代碼來添加班級,學生項的。


而後在 Res 中添加兩個新 Empty xib 文件:StudentView.xib 和 ClassView.xib,分別向這兩個 xib 文件中拖入一個 Custom View,而後在這個 view 添加相關控件構成 UI。記得設置 ClassView 中兩個 tableView 的列數爲 1,拖入一個 PopupButtonCell 到 StudentView 中班級那一列。效果以下:
 

6,添加 ViewController:
下面咱們建立 ViewController 來在程序中轉載 xib 文件,顯示和切換 view。爲了便於切換 view,咱們建立一個繼承自 NSViewController 的名爲:ManagedViewController的類(記得不要建立該類對應的 xib 文件!建立一個 NSObject子類,而後修改其父類爲 NSViewController),而後讓 StudentViewController 和 ClassViewController 從它繼承。ManagedViewController 類的代碼以下:
ManagedViewController.h

  1. #import <Cocoa/Cocoa.h>  
  2.   
  3. @interface ManagedViewController : NSViewController {  
  4. @private  
  5.     NSManagedObjectContext * managedObjectContext;  
  6.     NSArrayController * contentArrayController;  
  7. }  
  8.   
  9. @property (nonatomic, retain) NSManagedObjectContext * managedObjectContext;  
  10. @property (nonatomic, retain) IBOutlet NSArrayController *contentArrayController;  
  11.   
  12. @end  

 


ManagedViewController.m

  1. #import "ManagedViewController.h"  
  2.   
  3. @implementation ManagedViewController  
  4.   
  5. @synthesize managedObjectContext;  
  6. @synthesize contentArrayController;  
  7.   
  8. - (void)dealloc  
  9. {  
  10.     self.contentArrayController = nil;  
  11.     self.managedObjectContext = nil;  
  12.   
  13.     [super dealloc];  
  14. }  
  15.   
  16. // deal with "Delete" key event.  
  17. //  
  18. - (void) keyDown:(NSEvent *)theEvent  
  19. {  
  20.     if (contentArrayController) {  
  21.         if ([theEvent keyCode] == 51) {  
  22.             [contentArrayController remove:nil];  
  23.         }  
  24.         else {  
  25.             [super keyDown:theEvent];  
  26.         }  
  27.     }  
  28.     else {  
  29.         [super keyDown:theEvent];  
  30.     }  
  31. }  
  32.   
  33. @end  


在上面代碼中,咱們有一個 NSManagedObjectContext * managedObjectContext 指針,它指向 MyDocument 框架中的NSManagedObjectContext對象,後面咱們會說到,至於 NSArrayController * contentArrayController,它是一個 IBOutlet,將與xib 中建立的 NSArrayController關聯,後面也會說到。在這裏引入 contentArrayController 是爲了讓 delete 可以刪除記錄。

ClassViewController 類的代碼以下:

  1. #import "ManagedViewController.h"  
  2.   
  3. @interface ClassViewController : ManagedViewController {  
  4. @private  
  5. }  
  6.   
  7. @end  
  8.   
  9. #import "ClassViewController.h"  
  10.   
  11. @implementation ClassViewController  
  12.   
  13. - (id)init  
  14. {  
  15.     self = [super initWithNibName:@"ClassView" bundle:nil];  
  16.     if (self) {  
  17.         [self setTitle:@"班級"];  
  18.     }  
  19.       
  20.     return self;  
  21. }  
  22.   
  23. - (void)dealloc  
  24. {  
  25.     [super dealloc];  
  26. }  
  27.   
  28. @end  


StudentViewController 類的代碼以下:

  1. #import "ManagedViewController.h"  
  2.   
  3. @interface StudentViewController : ManagedViewController {  
  4. @private  
  5. }  
  6.   
  7. @end  
  8.   
  9. #import "StudentViewController.h"  
  10.   
  11. @implementation StudentViewController  
  12.   
  13. - (id)init  
  14. {  
  15.     self = [super initWithNibName:@"StudentView" bundle:nil];  
  16.     if (self) {  
  17.         [self setTitle:@"學生"];  
  18.     }  
  19.       
  20.     return self;  
  21. }  
  22.   
  23. - (void)dealloc  
  24. {  
  25.     [super dealloc];  
  26. }  
  27.   
  28. @end  


在這兩個子類中,咱們在 init 方法中載入 xib 文件,而後設置其 title。

相關文章
相關標籤/搜索