举例说明 归档/反归档(序列化/反序列化)

本篇文章是对于复杂对象来说的 这里我们来实现一个通讯录的功能 这个通讯录一共有三个页面:
(1) 主页面 显示名字的tableView
(2) 点击主页面中的cell可以跳转到个人详情页面(在这个页面中 可以在textField中修改联系人的信息) 修改完信息后 点击修改完成按钮 跳转回主页 这时要将修改完的数据也返回到主页 并在主页将返回的数据添加到数组中
更新tableView (注意: 这时将数据返回主页就不是简单的add添加到数组中就行了 这里要注意插入所修改的数据的位置 因为我们所修改不一定是哪一行cell 所以当我们在主页点击cell跳转到第二页修改页的时候 要利用属性传值向第二页传一个位置的参数 也就是indexPath.row(做法是 在第二页的.h文件中设置一个NSInteger属性 在tableView的点击方法中 将indexPath.row赋值给第二页的NSInteger属性) 当修改完信息后 点击修改完成 这时要返回主页 我们要把修改完的数据也返回到主页 我们用到协议传值(创建协议 写协议方法 设置协议属性 签订协议 设置代理人 实现协议方法 触发协议 协议方法应该要返回两个参数给主页 (1)对象 也就是将修改完的对象返回到主页 (2) 位置信息 也就是从主页传到第二页的indexPath 我们还需要将他返回到主页) 我们通过利用协议传值 将修改好的对象和一个位置信息都传到了主页 我们在主页中实现协议方法 也就是将返回来的对象添加到主页数据数组中 由于这是在修改信息 所以要先把修改之前的信息删除然后再添加这个返回来的修改完的对象 这是我们就要用到我们从主页传到第二页的位置属性indexPath 我们先删除 再插入 这是数组中的信息就已经更新完毕了 我们将这个更新完的数组进行归档 覆盖掉之前的旧数组就可以了)

(3) 在主页面的navigationBar上创建一个右按钮 点击这个按钮 跳转到第三页 第三页的textField都是空的 我们在这里添加新的联系人信息 然后点击第三页的"添加完成"按钮 将添加好的信息(也就是对象)返回到主页 将新添加的信息添加到主页数据数组中 再将这个数组归档覆盖掉原来的数据 这样就添加完成了

除了添加联系人信息 修改信息 我们还实现了删除联系人的功能 其实重要的是要记住无论我们做过了什么操作 只要处理好数据源将新的数据归档 覆盖掉旧的数据就可以实现相应的功能了

下面我们根据代码来分析一下

  1. 首先我们还是先传建一个window 将ViewController设置为根视图

     #import "AppDelegate.h"
     #import "ViewController.h"
    
     @interface AppDelegate ()
    
     @end
    
     @implementation AppDelegate
    
     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // Override point for customization after application launch.
     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
     [self.window makeKeyAndVisible];
     self.window.backgroundColor = [UIColor whiteColor];
     ViewController *vc = [[ViewController alloc] init];
     UINavigationController *nav =   [[UINavigationController alloc] initWithRootViewController:vc];
     self.window.rootViewController = nav;
     return YES;
     }
    
  2. 我们在根视图控制器中创建tableView
    #import "ViewController.h"
    #define kTableView @"reuse"
    #import "Contact.h"
    #import "ContentViewController.h"
    #import "AddViewController.h"

     @interface ViewController ()   <UITableViewDelegate, UITableViewDataSource,     ContentViewControllerDelegate,   AddViewControllerDelegate>
     @property (nonatomic, strong) UITableView *contactTableView;
     @property (nonatomic, strong) NSMutableArray *dataArray;
     @property (nonatomic, copy) NSString *arrayPath;
    
     @end
    
     @implementation ViewController
    
     - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view, typically from a nib.
               self.navigationController.navigationBar.backgroundColor = [UIColor grayColor];
     self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]   initWithBarButtonSystemItem:UIBarButtonSystemI      temAdd target:self action:@selector(click:)];
     [self createTableView];
     [self createData];
    
     }
    
     - (void)click:(UIButton *)button {
     // 跳转到添加页面
     AddViewController *vc = [[AddViewController alloc] init];
     // 在跳转到田间页面的点击方法中指定代理人
     vc.delegate = self;
     [self.navigationController pushViewController:vc animated:YES];
     }
    
     - (void)sendAddContact:(Contact *)contact {
     // 在主页中实现添加页面的协议方法
     // 将从添加页传来的新数据添加到数据数组中
     [self.dataArray addObject:contact];
     // 刷新tableView
     [self.contactTableView reloadData];
     // 将添加数据后的新数组归档本地 覆盖之前的数据
     [NSKeyedArchiver archiveRootObject:self.dataArray   toFile:self.arrayPath];
     }
    
     - (void)createData {
     // 创建沙盒路径
     NSArray *sandArray =     NSSearchPathForDirectoriesInDomains(NSDocum  entDirectory, NSUserDomainMask, YES);
     NSString *path = [sandArray firstObject];
     // 拼接一个路径 这个路径就是我们数据的路径
     self.arrayPath = [path stringByAppendingPathComponent:@"contactPerson.plist"];
     // 我们通过之前的路径 反归档 从本地返回一个数组
     NSArray *unarchiveArray = [NSKeyedUnarchiver unarchiveObjectWithFile:_arrayPath];
     // 判断 如果数组中内容不为空 就把这个反归档的数组赋值给我们的数据数组
     if (unarchiveArray.count != 0) {
     self.dataArray = [NSMutableArray arrayWithArray:unarchiveArray];
     }
     else {
     // 如果反归档返回的是一个空的数组我们就向我们的数据数组中添加一个对象(其实都不需要这个判断的 我们就直接将反归档 返回的数组直接赋值给我们的数据数组就可以 这里 我们为了不让主页是空白的 就判断了一下 如果是空的就赋一个初始的对象)
     Contact *contact1 = [[Contact alloc] initWithPicImage:@"fsds" name:@"Eason" phoneNum:@"123456" address:@"香港"];
     self.dataArray = [NSMutableArray array];
     [_dataArray addObject:contact1];
     [NSKeyedArchiver archiveRootObject:_dataArray toFile:_arrayPath];
     }
     NSLog(@"%@", _arrayPath);
     }  
    
     - (void)createTableView {
     self.contactTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
     self.contactTableView.delegate = self;
     self.contactTableView.dataSource = self;
     [self.view addSubview:self.contactTableView];
     [self.contactTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kTableView];
     }
    
     // 实现删除功能 这是tableView编辑中的内容 
     - (void)tableView:(UITableView *)tableView commitEditingStyle:  (UITableViewCellEditingStyle)editingStyle   forRowAtIndexPath:(NSIndexPath *)indexPath {
     // 要想删除联系人 我们要清楚都要删除哪些内容 首先要实现删除我们的数据数组相对应的对象数据然后要删除对应的tableView的cell() 然后就是处理之前本地存储的数据了 我们只需要将更新后的数据数组再次归档就可以更新本地数据了
     [self.dataArray removeObjectAtIndex:indexPath.row];
     [self.contactTableView deleteRowsAtIndexPaths:@[indexPath]   withRowAnimation:UITableViewRowAnimationFade];
     [NSKeyedArchiver archiveRootObject:self.dataArray toFile:self.arrayPath];
     [self.contactTableView reloadData];
     }
    
     - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return self.dataArray.count;
     }
    
     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kTableView forIndexPath:indexPath];
     cell.textLabel.text = [self.dataArray[indexPath.row] name];
     return cell;
     }
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ContentViewController *vc =     [[ContentViewController alloc] init];
     // 签订修改信息的协议
     vc.delegate = self;
     // 将数据所在数组的下标传值给修改页面
     vc.index = indexPath.row; 
     vc.contact = self.dataArray[indexPath.row];
     [self.navigationController     pushViewController:vc animated:YES];
     }
     // 实现修改页的协议方法
     - (void)sendContact:(Contact *)contact index:(NSInteger)index {
     // 先移除数据数组中对应位置的数据
     [self.dataArray removeObjectAtIndex:index];
     // 再将修改后的数据插入到数组中
     [self.dataArray insertObject:contact atIndex:index];
     [self.contactTableView reloadData];
     // 再将更新后的数组归档 覆盖掉之前的旧数据
     [NSKeyedArchiver archiveRootObject:self.dataArray toFile:self.arrayPath];
     }  
    
  3. 添加新联系人页面

     #import <UIKit/UIKit.h>
     #import "Contact.h"
     // 创建协议 利用协议实现将添加页添加的数据传到主页面
     @protocol AddViewControllerDelegate <NSObject>
    
     - (void)sendAddContact:(Contact *)contact;
    
    @end
    
    @interface AddViewController :     UIViewController
    @property (nonatomic, strong) Contact *contact;
    @property (nonatomic, weak) id<AddViewControllerDelegate>delegate;
    @end
    
     #import "AddViewController.h"
    
     @interface AddViewController ()
     @property (nonatomic, strong)     UIImageView *picImageView;
     @property (nonatomic, strong) UITextField *nameTextField;
     @property (nonatomic, strong) UITextField *phoneNumTextField;
     @property (nonatomic, strong) UITextField *addressTextField;
    
     @property (nonatomic, strong) UIButton *addButton;
     @end
    
     @implementation AddViewController
    
     - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     self.navigationController.navigationBar.translucent = NO;
     [self createView];
     }
    
     - (void)createView {
     UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 240, 60, 30)];
     nameLabel.text = @"姓名";
     [self.view addSubview:nameLabel];
     UILabel *phoneLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 340, 60, 30)];
     phoneLabel.text = @"电话";
     [self.view addSubview:phoneLabel];
     UILabel *addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 290, 60, 30)];
     addressLabel.text = @"地址";
     [self.view addSubview:addressLabel];
    
     self.picImageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 10, 150, 200)];
     self.picImageView.backgroundColor = [UIColor redColor];
     [self.view addSubview:self.picImageView];
    
     self.nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(160, 240, 200, 30)];
     [self.view addSubview:self.nameTextField];
    
     self.addressTextField = [[UITextField alloc] initWithFrame:CGRectMake(160, 290, 200, 30)];
     [self.view addSubview:self.addressTextField];
    
     self.phoneNumTextField = [[UITextField alloc] initWithFrame:CGRectMake(160, 340, 200, 30)];
     [self.view addSubview:self.phoneNumTextField];
    
     self.addButton = [UIButton buttonWithType:UIButtonTypeSystem];
     self.addButton.frame = CGRectMake(80, 390, 90, 30);
     [self.addButton setTitle:@"添加完成" forState:UIControlStateNormal];
     [self.view addSubview:self.addButton];
     [self.addButton addTarget:self action:@selector(addClick:)   forControlEvents:UIControlEventTouchUpInside];
     }
    
     - (void)addClick:(UIButton *)button {
     // 在添加完成的点击方法中创建一个对象 给对象进行赋值
     self.contact = [[Contact alloc] initWithPicImage:@"u=3808451166,1723806820&fm=23&gp=0" name:self.nameTextField.text phoneNum:self.phoneNumTextField.text address:self.addressTextField.text];
     // 这里触发协议方法 将添加的信息传到主页
     [self.delegate sendAddContact:self.contact];
     [self.navigationController popToRootViewControllerAnimated:YES];
     }
    
  4. 修改联系人信息的页面

     #import <UIKit/UIKit.h>
     #import "Contact.h"
     // 创建协议 利用协议将修改后的数据传到主页
     @protocol ContentViewControllerDelegate <NSObject>
     // 修改
     - (void)sendContact:(Contact *)contact index:(NSInteger)index;
    
     @end
    
     @interface ContentViewController : UIViewController
     @property (nonatomic, assign) NSInteger index;
     @property (nonatomic, strong) Contact *contact;
     @property (nonatomic, weak) id <ContentViewControllerDelegate>delegate;
     @end
    
     #import "ContentViewController.h"
    
     @interface ContentViewController ()
    
     @property (nonatomic, strong) UIImageView *picImageView;
     @property (nonatomic, strong) UITextField *nameTextField;
     @property (nonatomic, strong) UITextField *phoneNumTextField;
     @property (nonatomic, strong) UITextField *addressTextField;
     @property (nonatomic, strong) UIButton *changeButton;
     @property (nonatomic, strong) NSMutableDictionary *textFieldDic;
     @end
    
     @implementation ContentViewController
    
     - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     self.navigationController.navigationBar.translucent = NO;
     [self createContentView];
    
     }
    
     - (void)createContentView {
     // 创建label
     UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 240, 60, 30)];
     nameLabel.text = @"姓名";
     [self.view addSubview:nameLabel];
     UILabel *phoneLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 340, 60, 30)];
     phoneLabel.text = @"电话";
     [self.view addSubview:phoneLabel];
     UILabel *addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 290, 60, 30)];
     addressLabel.text = @"地址";
     [self.view addSubview:addressLabel];
    
     self.picImageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 10, 150, 200)];
     self.picImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@", self.contact.picImage]];
     self.picImageView.backgroundColor = [UIColor redColor];
     [self.view addSubview:self.picImageView];
    
     self.nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(160, 240, 200, 30)];
     self.nameTextField.text = self.contact.name;
     [self.view addSubview:self.nameTextField];
    
     self.addressTextField = [[UITextField alloc] initWithFrame:CGRectMake(160, 290, 200, 30)];
     self.addressTextField.text = self.contact.address;
     [self.view addSubview:self.addressTextField];
    
     self.phoneNumTextField = [[UITextField alloc] initWithFrame:CGRectMake(160, 340, 200, 30)];
     self.phoneNumTextField.text = self.contact.phoneNum;
     [self.view addSubview:self.phoneNumTextField];
    
     self.changeButton = [UIButton buttonWithType:UIButtonTypeSystem];
     self.changeButton.frame = CGRectMake(80, 390, 90, 30);
     [self.changeButton setTitle:@"修改完成" forState:UIControlStateNormal];
     [self.view addSubview:self.changeButton];
     [self.changeButton addTarget:self action:@selector(changeClick:) forControlEvents:UIControlEventTouchUpInside];
    
     }
    
     // 修改信息
     - (void)changeClick:(UIButton *)button {
     self.contact = [[Contact alloc] initWithPicImage:@"u=3808451166,1723806820&fm=23&gp=0.jpg" name:self.nameTextField.text phoneNum:self.phoneNumTextField.text address:self.addressTextField.text];
     [self.delegate sendContact:self.contact index:self.index];
     [self.navigationController popToRootViewControllerAnimated:YES];
     }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容