美文网首页
举例说明 归档/反归档(序列化/反序列化)

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

作者: 9bf19a4010ab | 来源:发表于2016-08-07 16:44 被阅读38次

    本篇文章是对于复杂对象来说的 这里我们来实现一个通讯录的功能 这个通讯录一共有三个页面:
    (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];
       }
      

    相关文章

      网友评论

          本文标题:举例说明 归档/反归档(序列化/反序列化)

          本文链接:https://www.haomeiwen.com/subject/drslsttx.html