文档章节

[Cocoa]深入浅出 Cocoa 之 Core Data(4)- 使用绑定

木木情深
 木木情深
发布于 2013/12/19 21:15
字数 1765
阅读 43
收藏 1

前面讲解了 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,表示该班的班长。

代码下载:点此下载

=========================================================================

接前半部分

7,创建 NSArrayController,关联对象
现在回到 xib 中来,选中 StudentView.xib,设置StudentView 的 File's Owner 的类为 StudentViewController;使用 Control-Drag 将 File's Owner 的 view 指向 custom view。

向其中拖入两个 NSArrayController:ClassPopup 和 Students。
设置 ClassPopup 的 Object Controller Mode 为 Entity Name,实体名为:ClassEntity,并勾选 Prepare Content。
设置 Students 的 Object Controller Mode 为 Entity Name,实体名为:StudentEntity,并勾选 Prepare Content。

上面的这些操作,ClassPopup ArrayController 管理 ClassEntity 的数据,Students ArrayController 管理 StudentEntity 的数据,后面我们就要将控件与这些 ArrayController 绑定起来。下面我们将这两个 NSArrayController 的 ManagedObjectContext 参数与 ManagedViewController(File's Owner) 中的 managedObjectContext 绑定起来,这样 NSDocuments 的 NSManagedObjectContext 就作用到的 ArrayController 中来了。下面只演示了 ClassPopup,请自行完成 Students 的绑定:

前面我们在 ManagedViewController 创建了一个 IBOutlet contentArrayController,现在是将它关联的时候了,使用 Control-Drag 将 File's Owner 的 contentArrayController 关联到 Students。

重复上面的过程,选中 ClassView.xib,将 File's Owner 的类为 ClassViewController,并将其 view 指向 custom view。
向其中拖入三个 NSArrayController:Classes,MonitorPopup 和 Students。
设置 Classes 的 Object Controller Mode 为 Entity Name,实体名为:ClassEntity,并勾选 Prepare Content。
将 Classes 的 ManagedObjectContext 参数与 ManagedViewController(File's Owner) 中的 managedObjectContext 绑定起来。
注意:这里没有对 MonitorPopup 和 Students 进行修改。
使用 Control-Drag 将 File's Owner 的 contentArrayController 关联到 Classes。

将 Students 和 MonitorPopup 的 Content set 绑定到 Classes 的  Model key path: students,表示这两个 ArrayController  是管理对应 ClassEntity 的 students 的数据。

至此,模型, ArrayController 都准备好了,下面我们将控件绑定到这些对象上。上面已经够繁琐的了,下面我们得更加仔细,很容易出错的。

选中 StudentView.xib,展开 Custom View 中的 TableView,直到我们看到名称和班级两个 Table Column。
选中名称列,将其 value 绑定到 Students,model key path 为:name,表明第一列显示学生的名称;
选择班级列,注意这一列是popup button cell,
将其 Content 绑定到 ClassPopup;
将其 ContentValues 绑定到 ClassPopup,model key path 为:name,表明第二列的选项为班级的名称;
将其 Selected Object 绑定到 Students,model key path 为:inClass;表明将学生添加为选中班级的一员;

选中 + button,使用 Control+Drag将其托拽到 Students 上,选择 add: 动作关联;
选中 - button,使用 Control+Drag将其托拽到 Students 上,选择 remove: 动作关联;
选中 - button,将其 Eanbled 绑定到 Students, ctroller key 为:canRemove;
以上操作是将添加,删除学生的操作直接与 Students ArrayController 绑定,无需编写一点儿代码!


选中 ClassView.xib
展开 Custom View 中的班级表,,直到我们看到班级 Table Column:选择班级列,将其 value 绑定到 Classes,model key path 为:name,表明这一列显示班级的名称;
选中 Box,将其 Title 绑定到 Classed,model key path 为:name,并设置下方的 No Selection Placeholder 为:No Selection,Null Placeholder 为:Unnamed Class。 表明 box 显示的信息为选中班级的信息,如果没有选中任何班级,则显示 No Selection。

展开 Box
选中 Pop up button
将其 Content 绑定到 MonitorPopup;
将其 ContentValues 绑定到 MonitorPopup,model key path 为:name,表明其选项为班级中的学生的名称;
将其 Selected Object 绑定到 Classes,model key path 为:monitor;表明将选中的学生当作该班级的班长;

展开学生 tabel view,直到我们看到学生这个 Table Column。
选择学生列,将其 Value 绑定到 Students,Model key path 为:name,表明学生列表显示该班级中所有学生的名称。

选中 + button,使用 Control+Drag 将其托拽到 Classes 上,选择 add: 动作关联;
选中 - button,使用 Control+Drag 将其托拽到 Classes 上,选择 remove: 动作关联;
选中 - button,将其 Eanbled 绑定到 Classes, ctroller key 为:canRemove;
以上操作是将添加,删除班级的操作直接与 Classes ArrayController 绑定。

至此,绑定也大功告成,如果你的程序运行不正确,多半是这地方的关联与绑定错了,请回到这部分,仔细检查每一项。

8,显示,切换 view。
现在到了设置主界面的时候,修改 MyDocument.h 中的代码如下:

[cpp]    view plain   copy   print   ?  

  1. #import <Cocoa/Cocoa.h>  

  2.   

  3. @class ManagedViewController;  

  4.   

  5. @interface MyDocument : NSPersistentDocument {  

  6. @private  

  7.     NSBox *         box;  

  8.     NSPopUpButton * popup;  

  9.       

  10.     NSMutableArray *viewControllers;  

  11.     NSInteger       currentIndex;  

  12. }  

  13.   

  14. @property (nonatomic, retain) IBOutlet NSBox *          box;  

  15. @property (nonatomic, retain) IBOutlet NSPopUpButton *  popup;  

  16.   

  17. - (IBAction) changeViewController:(id)sender;  

  18. - (void) displayViewController:(ManagedViewController *)mvc;  

  19.   

  20. @end  


修改 MyDocument.m  中的代码如下:

[cpp]    view plain   copy   print   ?  

  1. #import "MyDocument.h"  

  2. #import "ClassViewController.h"  

  3. #import "StudentViewController.h"  

  4.   

  5. @implementation MyDocument  

  6.   

  7. @synthesize popup;  

  8. @synthesize box;  

  9.   

  10. - (id)init  

  11. {  

  12.     self = [super init];  

  13.     if (self) {  

  14.         // create view controllers  

  15.         //  

  16.         viewControllers = [[NSMutableArray alloc] init];  

  17.           

  18.         ManagedViewController * mvc;  

  19.         mvc = [[ClassViewController alloc] init];  

  20.         [mvc setManagedObjectContext:[self managedObjectContext]];  

  21.         [viewControllers addObject:mvc];  

  22.         [mvc release];  

  23.           

  24.         mvc = [[StudentViewController alloc] init];  

  25.         [mvc setManagedObjectContext:[self managedObjectContext]];  

  26.         [viewControllers addObject:mvc];  

  27.         [mvc release];  

  28.     }  

  29.     return self;  

  30. }  

  31.   

  32. - (void) dealloc  

  33. {  

  34.     self.box = nil;  

  35.     self.popup = nil;  

  36.     [viewControllers release];  

  37.       

  38.     [super dealloc];  

  39. }  

  40.   

  41. - (NSString *)windowNibName  

  42. {  

  43.     // Override returning the nib file name of the document  

  44.     // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.  

  45.     return @"MyDocument";  

  46. }  

  47.   

  48. - (void)windowControllerDidLoadNib:(NSWindowController *)aController  

  49. {  

  50.     [super windowControllerDidLoadNib:aController];  

  51.   

  52.     // init popup  

  53.     //  

  54.     NSMenu *menu = [popup menu];  

  55.     NSInteger itemCount = [viewControllers count];  

  56.       

  57.     for (NSInteger i = 0; i < itemCount; i++) {  

  58.         NSViewController *vc = [viewControllers objectAtIndex:i];  

  59.         NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[vc title]  

  60.                                                       action:@selector(changeViewController:)  

  61.                                                keyEquivalent:@""];  

  62.         [item setTag:i];  

  63.         [menu addItem:item];  

  64.         [item release];  

  65.     }  

  66.       

  67.     // display the first controller  

  68.     //  

  69.     currentIndex = 0;  

  70.     [self displayViewController:[viewControllers objectAtIndex:currentIndex]];  

  71.     [popup selectItemAtIndex:currentIndex];  

  72. }  

  73.   

  74. #pragma mark -  

  75. #pragma mark Change Views  

  76.   

  77. - (IBAction) changeViewController:(id)sender  

  78. {  

  79.     NSInteger tag = [sender tag];  

  80.     if (tag == currentIndex) {  

  81.         return;  

  82.     }  

  83.       

  84.     currentIndex = tag;  

  85.     ManagedViewController *mvc = [viewControllers objectAtIndex:currentIndex];  

  86.     [self displayViewController:mvc];  

  87. }  

  88.   

  89. - (void) displayViewController:(ManagedViewController *)mvc  

  90. {  

  91.     NSWindow *window = [box window];  

  92.     BOOL ended = [window makeFirstResponder:window];  

  93.     if (!ended) {  

  94.         NSBeep();  

  95.         return;  

  96.     }  

  97.       

  98.     NSView *mvcView = [mvc view];  

  99.       

  100.     // Adjust window's size and position  

  101.     //  

  102.     NSSize currentSize      = [[box contentView] frame].size;  

  103.     NSSize newSize          =  [mvcView frame].size;  

  104.     float deltaWidth        = newSize.width - currentSize.width;  

  105.     float deltaHeight       = newSize.height - currentSize.height;  

  106.       

  107.     NSRect windowFrame      = [window frame];  

  108.     windowFrame.size.width  += deltaWidth;  

  109.     windowFrame.size.height += deltaHeight;  

  110.     windowFrame.origin.y    -= deltaHeight;  

  111.       

  112.     [box setContentView:nil];  

  113.     [window setFrame:windowFrame display:YES animate:YES];  

  114.       

  115.     [box setContentView:mvcView];  

  116.       

  117.     // add viewController to the responder-chain  

  118.     //  

  119.     [mvcView setNextResponder:mvc];  

  120.     [mvc setNextResponder:box];  

  121. }  

  122.   

  123. @end  


在 MyDocument 中,我们创建了两个 ManagedViewController,并将 managedObjectContext 传入其中。这两个ViewController分别代表班级与学生两个界面,然后通过 popup button 的选择在他们之间切换显示;在 displayViewController 中,我们还根据当前界面的大小来调整主界面的大小。这需要我们设置主界面中 box 的自动大小。打开 MyDocument.xib,作如下设置:


然后,使用 Control+Drag,将 File's Owner的 popup 和 popup button相联,box 与 box相联,并将 popup button 的 action 设置为 File's Owner 的 - (IBAction) changeViewController:(id)sender。

至此,所有的工作都完成了。编译运行程序,如果不出意外的话,我们应该可以添加学生,班级,并设置学生的班级,班级的班长等信息了。

本文转载自:http://blog.csdn.net/kesalin/article/details/6757412

木木情深
粉丝 37
博文 189
码字总数 26451
作品 0
广州
程序员
私信 提问
[Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解

Core data 是 Cocoa 中处理数据,绑定数据的关键特性,其重要性不言而喻,但也比较复杂。Core Data 相关的类比较多,初学者往往不太容易弄懂。计划用三个教程来讲解这一部分: 框架详解:讲解...

木木情深
2013/12/19
0
0
深入浅出 Cocoa 之 Core Data(1) - 框架详解

深入浅出 Cocoa 之 Core Data(1) - 框架详解 罗朝辉(http://www.cppblog.com/kesalin) CC 许可,转载请注明出处 Core data 是 Cocoa 中处理数据,绑定数据的关键特性,其重要性不言而喻,但...

jackyyang
2012/07/12
0
0
Core Data 学习笔记 常用链接整理

目录 Core Data 学习笔记(一)框架简介 Core Data 学习笔记(二)被管理对象模型 Core Data 学习笔记(三)被管理对象 Core Data 学习笔记 应用示例 Core Data 学习笔记 常用链接整理 文章 ...

灰大羊
2015/07/31
0
0
iOS开发之Object-C和Cocoa [转]

Objective-C Objective-C,是扩充C的面向对象编程语言。是在C的基础上,加入面向对象特性扩充而成的编程语言。目前,Objective-C主要应用于Mac OS X和iOS开发,而在NeXTSTEP和OpenStep中它更...

ilscott
2012/12/13
0
0
Core Data 学习笔记(三)被管理对象

目录 Core Data 学习笔记(一)框架简介 Core Data 学习笔记(二)被管理对象模型 Core Data 学习笔记(三)被管理对象 Core Data 学习笔记 应用示例 Core Data 学习笔记 常用链接整理 五、被...

灰大羊
2015/07/29
125
0

没有更多内容

加载失败,请刷新页面

加载更多

Bash 和 Python 编程语言优缺点分析

Bash 和 Python 是大多数自动化工程师最喜欢的编程语言。它们都各有优缺点,有时很难选择应该使用哪一个。所以,最诚实的答案是:这取决于任务、范围、背景和任务的复杂性。 让我们来比较一下...

xiangyunyan
21分钟前
3
0
Kubernetes从懵圈到熟练:读懂这一篇,集群节点不下线

排查完全陌生的问题,完全不熟悉的系统组件,是售后工程师的一大工作乐趣,当然也是挑战。今天借这篇文章,跟大家分析一例这样的问题。排查过程中,需要理解一些自己完全陌生的组件,比如sys...

阿里云云栖社区
26分钟前
4
0
解决exe4打包出现的问题

https://blog.csdn.net/gem_yaorao/article/details/48626155

南桥北木
42分钟前
1
0
SpringBoot高级篇JdbcTemplate之数据更新与删除

前面介绍了JdbcTemplate的插入数据和查询数据,占用CURD中的两项,本文则将主要介绍数据更新和删除。从基本使用上来看,姿势和前面的没啥两样 <!-- more --> I. 环境准备 环境依然借助前面一...

小灰灰Blog
59分钟前
3
0
Filecoin 编译问题

https://github.com/filecoin-project/go-filecoin/issues/2503 Error go run ./build build command from root I've faced on this error Building go-filecoin...git log -n 1 --forma......

怎当她临去时秋波那一转
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部