前面的博文里介绍了归档和解档,这里我们把它实际应用到一个简单的代码中去,将它作为一个多文档应用程序的打开和保存的背后支持。另外这里介绍一下MVC思想,这个在不论什么语言里都会有,它是一种设计思想,主要能够概括为一个程序由3部分组成:

1 模式:是程序的数据支持;

2 视图:是程序的表示支持;

3 控制:连接模式和视图,将程序构为一个总体;

Cocoa框架中对MVC提供了非常好的支持,你仅仅须要写非常少的代码就能够完毕一个程序的MVC绑定了。以下的样例中,我生成一个基于多文档的程序,使用了NSArrayController类作为控制器,它的数据源为NSArray,当中每个元素由我定义的类Person来描写叙述;主窗体中的tab_view作为主类中的outlets,主类为Document,它派生自NSDocument用来支持多文档中的每个文档窗体。

加入add和removebutton,都与NSArrayController中的add和remove方法绑定;tab_view控件的两列分别与Person类中的2个属性绑定,每一行自然是Person数组中的每个Person对象了。这样每个视图中的数据表示(tab_view)通过控制器与模式相连,视图内容的改变(通过add和removebutton)也通过控制器从而导致模式数据的改变;而模式自身的改变(通过读档操作)也会更新视图的显示哦。这样保证了视图和模式的独立性:模式能够在其它视图上显示,而视图也能够绑定其它的模式。

最后,利用归档化实现了程序的save和open功能,也基本没写几行代码,并且save后的文件也自己主动与我们的程序绑定起来,假设双击该文件,会自己主动用我们的app打开哦,真是十分的方便。详细请看代码:

//
// Document.h
// mac_doc
//
// Created by kinds on 14-7-7.
// Copyright (c) 2014年 kinds. All rights reserved.
// #import <Cocoa/Cocoa.h> @interface Document : NSDocument{
IBOutlet NSTableView *tab_view;
NSMutableArray *persons;
} -(void)setPersons:(NSMutableArray *)ary; @end
//
// Document.m
// mac_doc
//
// Created by kinds on 14-7-7.
// Copyright (c) 2014年 kinds. All rights reserved.
// #import "Document.h" @interface Document () @end @implementation Document - (instancetype)init {
self = [super init];
if (self) {
// Add your subclass-specific initialization here.
persons = [[NSMutableArray alloc]init];
}
return self;
} -(void)setPersons:(NSMutableArray *)ary{
if(ary == persons) return;
persons = ary;
} - (void)windowControllerDidLoadNib:(NSWindowController *)aController {
[super windowControllerDidLoadNib:aController]; // Add any code here that needs to be executed once the windowController has loaded the document's window. } + (BOOL)autosavesInPlace {
return YES;
} - (NSString *)windowNibName {
// Override returning the nib file name of the document
// 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.
return @"Document";
} - (NSData *)dataOfType:(NSString *)name error:(NSError **)out_err {
// Insert code here to write your document to data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning nil.
// You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
[[tab_view window] endEditingFor:nil];
return [NSKeyedArchiver archivedDataWithRootObject:persons];
} - (BOOL)readFromData:(NSData *)data ofType:(NSString *)name \
error:(NSError **)out_err {
// Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning NO.
// You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
// If you override either of these, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded.
NSMutableArray *new_ary = nil;
@try{
new_ary = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}@catch(NSException *e){
NSLog(@"exception = %@",e);
if(out_err){
NSDictionary *d = [NSDictionary dictionaryWithObject:\
@"data is corrupted!" \
forKey:NSLocalizedFailureReasonErrorKey];
*out_err = [NSError errorWithDomain:NSOSStatusErrorDomain \
code:unimpErr userInfo:d];
}
return NO;
}
[self setPersons:new_ary];
return YES;
} @end
//
// Person.h
// mac_doc
//
// Created by kinds on 14-7-7.
// Copyright (c) 2014年 kinds. All rights reserved.
// #import <Foundation/Foundation.h> @interface Person : NSObject <NSCoding>{
NSString *name;
float exp_raise;
} @property(readwrite,copy)NSString *name;
@property(readwrite)float exp_raise; @end
//
// Person.m
// mac_doc
//
// Created by kinds on 14-7-7.
// Copyright (c) 2014年 kinds. All rights reserved.
// #import "Person.h" @implementation Person @synthesize name,exp_raise; -(id)initWithCoder:(NSCoder *)coder{
self = [super init];
if(self){
name = [coder decodeObjectForKey:@"name"];
exp_raise = [coder decodeFloatForKey:@"exp_raise"];
}
return self;
} -(void)encodeWithCoder:(NSCoder *)coder{
[coder encodeObject:name forKey:@"name"];
[coder encodeFloat:exp_raise forKey:@"exp_raise"];
} -(id)init{
self = [super init];
if(self){
exp_raise = 0.05;
name = @"no_name";
}
return self;
} -(void)setNilValueForKey:(NSString *)key{
if([key isEqualToString:@"exp_raise"])
self.exp_raise = 0.0;
else
[super setNilValueForKey:key];
} @end

程序运行界面例如以下:

我们还能够设置私有存档文件的图标以及扩展名,例如以下图:

obj-c编程15[Cocoa实例03]:MVC以及归档化演示样例的更多相关文章

  1. obj-c编程15[Cocoa实例03]:MVC以及归档化示例

    前面的博文里介绍了归档和解档,这里我们把它实际应用到一个简单的代码中去,将它作为一个多文档应用程序的打开和保存的背后支持.另外这里介绍一下MVC思想,这个在任何语言里都会有,它是一种设计思想,主要可以 ...

  2. [原创]obj-c编程15[Cocoa实例02]:KVC和KVO的实际运用

    原文链接:obj-c编程15[Cocoa实例02]:KVC和KVO的实际运用 我们在第16和第17篇中分别介绍了obj-c的KVC与KVO特性,当时举的例子比较fun,太抽象,貌似和实际不沾边哦.那么 ...

  3. 【UNIX网络编程(三)】TCP客户/server程序演示样例

    上一节给出了TCP网络编程的函数.这一节使用那些基本函数编写一个完毕的TCP客户/server程序演示样例. 该样例运行的过程例如以下: 1.客户从标准输入读入一行文本,并写给server. 2.se ...

  4. obj-c编程15[Cocoa实例01]:一个会发声的随机数生成器

    哇!终于到了obj-c编程系列的第15篇喽,一路走过来满不容易的哦!(怎么个意思,这才哪到哪啊!),为了能够更好的练习obj-c在Cocoa框架上的编程,接下来会以N篇Cocoa实例的博文来巩固和记忆 ...

  5. obj-c编程15[Cocoa实例02]:KVC和KVO的实际运用

    我们在第16和第17篇中分别介绍了obj-c的KVC与KVO特性,当时举的例子比较fun,太抽象,貌似和实际不沾边哦.那么下面我们就用一个实际中的例子来看看KVC与KVO是如何运用的吧. 该例中用到了 ...

  6. obj-c编程15[Cocoa实例04]:基于Core Data的多文档程序示例[未完待续]

    上一个例子我们使用的模式数据实际上是基于一个Person数组,现在我们看一下如何使用Cocoa中的Core Data框架支持,几乎不用写一行代码,完成模式数据的建立. 我们这里模式的元素使用的是Car ...

  7. MVC模式编程演示样例-登录验证(静态)

    好,上篇博客分享了本人总结的JSP-Servlet-JavaBean三层架构编程模式的实现思想和基本流程,接下来给大家分享一个MVC编程模式的实现演示样例-登录验证的过程,这里我仍然用的是静态的验证u ...

  8. Android中MVP模式与MVC模式比較(含演示样例)

    原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...

  9. C编程规范, 演示样例代码。

    /*************************************************************** *Copyright (c) 2014,TianYuan *All r ...

随机推荐

  1. 他们主动布局(autolayout)环境的图像编辑器

    hi,all: 在经过了一番犹豫之后.我决定将我自己做的这个小APP的源代码发布给大家: 其出发点是和大家一起学习iOS开发.仅供学习參考之用. 之前代码是托管与gitlab 上的,今天我将其pull ...

  2. 开源Math.NET基础数学类库使用(05)C#解析Delimited Formats数据格式

    原文:[原创]开源Math.NET基础数学类库使用(05)C#解析Delimited Formats数据格式 开源Math.NET基础数学类库使用系列文章总目录:   1.开源.NET基础数学计算组件 ...

  3. 【Java基础】System.arraycopy()的使用详解

    由于在Java中System.arraycopy()方法在一维数组和二维数组中的表现不同,所以做了一个测试 public static void main(String[] args) { int[] ...

  4. iOS 中国排序

    这里分享一个中国某种方便的方法,我们放在一起的人脉资源后,方便的类别,使用自己的包, 此处所使用的方法贴,源代码可以在本文的结尾下载. 要记得加头文件 #import "NSArray+So ...

  5. Android View系统解析(上)

  6. HDOJ 4745 Two Rabbits DP

    Two Rabbits Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Tot ...

  7. 【Spark亚太研究院系列】Spark道路的真正的主人-第一章 构建Spark星团(第五步)(6)

    结束historyserver例如,下面的命令可以看到: 第四步:验证Hadoop分布式集群 首先在hdfs文件系统上创建两个文件夹.创建步骤例如以下所看到的: watermark/2/text/aH ...

  8. HDU 1195 Open the Lock (双宽搜索)

    意甲冠军:给你一个初始4数字和目标4数字,当被问及最初的目标转换为数字后,. 变换规则:每一个数字能够加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的). 双向广搜:分别 ...

  9. Android使用SVG矢量创建很酷的动态效率!

    尊重原创,欢迎转载.转载请注明: FROM  GA_studio   http://blog.csdn.net/tianjian4592 一个真正酷炫的动效往往让人虎躯一震,话不多说.咱们先瞅瞅效果: ...

  10. 5.非关系数据库(Nosql)它mongodb:创建一个集合,导出和导入备份, 数据恢复,进出口

     1 固定集合 固定集合值得是事先创建并且大小固定的集合 2 固定集合的特征:固定集合非常像环形队列.假设空间不足,最早文档就会被删除,为新的文档腾出空间.一般来说.固定集合适用于不论什么想要自己 ...