obj-c編程15[Cocoa執行個體03]:MVC以及歸檔化樣本

來源:互聯網
上載者:User

標籤:objecitve-c   cocoa   歸檔   mvc   

    前面的博文裡介紹了歸檔和解檔,這裡我們把它實際應用到一個簡單的代碼中去,將它作為一個多文檔應用程式的開啟和儲存的背後支援。另外這裡介紹一下MVC思想,這個在任何語言裡都會有,它是一種設計思想,主要可以概括為一個程式由3部分組成:

1 模式:是程式的資料支援;

2 視圖:是程式的表示支援;

3 控制:串連模式和視圖,將程式構為一個整體;

    Cocoa架構中對MVC提供了非常好的支援,你只需要寫很少的代碼就可以完成一個程式的MVC綁定了。下面的例子中,我產生一個基於多文檔的程式,使用了NSArrayController類作為控制器,它的資料來源為NSArray,其中每個元素由我定義的類Person來描述;主視窗中的tab_view作為主類中的outlets,主類為Document,它派生自NSDocument用來支援多文檔中的每一個文件視窗。


添加add和remove按鈕,都與NSArrayController中的add和remove方法綁定;tab_view控制項的兩列分別與Person類中的2個屬性綁定,每一行自然是Person數組中的每一個Person對象了。這樣每個視圖中的資料表示(tab_view)通過控制器與模式相連,視圖內容的改變(通過add和remove按鈕)也通過控制器從而導致模式資料的改變;而模式自身的改變(通過讀檔操作)也會更新視圖的顯示哦。這樣保證了視圖和模式的獨立性:模式可以在其他視圖上顯示,而視圖也可以綁定其他的模式。

    最後,利用歸檔化實現了程式的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

程式執行介面如下:


我們還可以設定私人封存檔案的表徵圖以及副檔名,如:



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.