前面的博文里介绍了归档和解档,这里我们把它实际应用到一个简单的代码中去,将它作为一个多文档应用程序的打开和保存的背后支持。另外这里介绍一下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. lua、groovy嵌入到java中的性能对比(转)

    lua和groovy都是可以嵌入到java中的脚本语言.lua以高性能著称,与C/C++在游戏开放中有较多使用,groovy是一个基于Java虚拟机(JVM)的敏捷动态语言,在jvm下有着不错的性能. ...

  2. Poj3414广泛搜索

    <span style="color:#330099;">/* D - D Time Limit:1000MS Memory Limit:65536KB 64bit I ...

  3. 开源Math.NET基础数学类库使用(01)综合介绍

    原文:[原创]开源Math.NET基础数学类库使用(01)综合介绍 开源Math.NET基础数学类库使用系列文章总目录:   1.开源.NET基础数学计算组件Math.NET(一)综合介绍    2. ...

  4. SDUTOJ 1298 活动选择

    #include<iostream> #include<memory.h> using namespace std; int a[105],b[105],c[105],d[10 ...

  5. QtQuick桌面应用程序开发指南 4)动态管理Note对象_B 5)加强外观 6)许多其他的改进

    4.2.2 Stateless(不管状态)JavaScript库 为了让开发轻松点, 使用一个JavaScript接口来和数据库交互是个好主意, 它在QML中提供了方便的方法; 在QtCreator中 ...

  6. sqlserver 无法初始化via支持库[QLVIPL.DLL]

    安装数据库后,在sqlserver configuration manager, sqlserver的网络配置,有将协议 shared memory,named pipes,tcp/ip,via全部启 ...

  7. Tuple

    Tuple(组元)是C# 4.0引入的一个新特性,编写的时候需要基于.NET Framework 4.0或者更高版本. 在以前编程中,当需要返回多个值得方法中,常常需要将这些值放置到一个结构体或者对象 ...

  8. js cookie设置最大过期时间 Infinity

    Note: 对于永久cookie我们用了Fri, 31 Dec 9999 23:59:59 GMT作为过期日.如果你不想使用这个日期,可使用世界末日Tue, 19 Jan 2038 03:14:07 ...

  9. 【2014】【】辛星【php】【秋】【1】php构建开发环境

    **************************什么是开发环境*********************** 1.我们学习PHP,是使用它来做web用的,通俗理解,就是做站点. 2.站点的执行须要 ...

  10. iOS 执行ScrollView在空白空间-解

    iOS7 中间UIViewControllers配置automaticallyAdjustsScrollViewInsets.假设YES.scrollview它会根据status bar, navig ...