• 私人通讯录


    一、私人通讯录

     

    什么是Segue

    ● Storyboard上每⼀一根⽤用来界⾯面跳转的线,都是⼀一个UIStoryboardSegue对象(简称Segue)

     

    "【登录界面】"

    1.掌握UIStoryboardSegue对象

    (1)storyboard中,可以通过连线完成多个界面间的跳转,每一连线我们称为segue

    (2)掌握storyboard中的segue连线有两种,一是自动跳转、二是手动跳转

    自动跳转从按钮连线,不管账号和密码是不是正确,就直接跳到下一个界面,而手动跳转,是用控制器开始连线。并设置segueIdentifier.

    (3)掌握如何使用代码跳转页面手动segue -->[self performSegueWithIdentifier:@"contactSegue" sender:nil];

    (4)掌握UIStoryboardSegue对象的源控制器和目标控制器

     

     

    2.掌握MBProgressHUD的使用,给用户一个友好的提示

     

    3.掌握控制器的数据传递

    (1) 在控制器的【-(void)prepareForSegue:sender:】的方法中获取目标控制器

    (2) 设置目标控制器的属性,可以实现数据的传递

     

    4.掌握文件框文字改变的监听

    方法1 使用通知中心

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.passwordField];

     

    方法2 往文本输入框添加事件

    addTarget: action: forControlEvents:UIControlEventEditingChanged

     

    方法3 storybaord连线

     

     

    5.掌握记住密码与自动登录逻辑

    (1)记住密码为关闭的情况下,如果自动登录为开启状态,应该关闭

    (2)如果自动登录为关闭状态,记住密码必需为开启状态

     

    "【添加联系人页面】"

    1.掌握数据的逆向传递

    (1)如果想向上一个控制器传递数据,可以使用代理的方法

    (2)向上个控制器传递数据时,可以传递字符串或者模型

     

    2.掌握表格的局部刷新,性能更好,使用【self.tableView insertRowsAtIndexPaths:withRowAnimation:】方法

     

    "【编辑联系人】"

    1.使用代理的方法通知上一个控制器联系个编辑完成,并保存

    2.刷新数据使用局部刷新【[self.tableView reloadRowsAtIndexPaths:withRowAnimation

     

    Main.storyboard

     

    cell的ID和添加联系人时可以防止cell右面没有数据(在Style中设置)

    LoginViewController.m

    //

    //  LoginViewController.m

    //  08.私人通讯录

    //

    //  Created by huan on 16/1/21.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "LoginViewController.h"

    #import "ContactsViewController.h"

    #import "MBProgressHUD+CZ.h"

     

    //定义用户偏好设置的key 防止写错

    #define rememberPwdKey @"rememberPwd" //记录密码

    #define autoLoginKey @"autoLogin"//自动登录

    #define accountKey @"account"//账号

    #define passwordKey @"password"//密码

    @interface LoginViewController ()

    @property (weak, nonatomic) IBOutlet UITextField *accoutField;

    @property (weak, nonatomic) IBOutlet UITextField *passwordField;

    - (IBAction)loginBtnClick;

    @property (weak, nonatomic) IBOutlet UIButton *loginBtn;

    @property (weak, nonatomic) IBOutlet UISwitch *rememberPwdSwitch;

    @property (weak, nonatomic) IBOutlet UISwitch *autoLoginSwitch;

     

    @end

     

    @implementation LoginViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view.

    #pragma mark 输入框里没有值,禁用登录按钮有3种方法(1)通知(2)添加事件(3)连线

        //使用通知中心来监听文本(TextField)的变化

    //    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.accoutField];

    //    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.passwordField];

        

        //textField 添加事件

    //    [self.accoutField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];

    //    [self.passwordField addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingChanged];

        

        //设置开关默认值

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        self.rememberPwdSwitch.on = [defaults boolForKey:rememberPwdKey];

        self.autoLoginSwitch.on = [defaults boolForKey:autoLoginKey];

        

        //设置账号和密码 默认值

        self.accoutField.text = [defaults objectForKey:accountKey];

        NSLog(@"++++++++++%@", NSHomeDirectory());

        if (self.rememberPwdSwitch.isOn) {

            self.passwordField.text = [defaults objectForKey:passwordKey];

        }

        //调用 文本 变化 的方法

        [self textChange];//解决登录按钮禁止的问题

        

        //如果自动登录勾选,让自动登录

        if (self.autoLoginSwitch.isOn) {

            [self loginBtnClick];

    //        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    //            [self loginBtnClick];

    //        });

        }

        

        NSLog(@"viewDidLoad 打印窗口%@",[UIApplication sharedApplication].windows);

     

    }

    // UITextEffectsWindow 给键盘,只有view显示完成之后才会创建

    -(void)viewDidAppear:(BOOL)animated{

        NSLog(@"viewDidAppear打印窗口%@", [UIApplication sharedApplication].windows);

        ;

    }

    //控制器已经销毁,不需要监听

    -(void)dealloc{

        //移除通知者中心

        [[NSNotificationCenter defaultCenter] removeObserver:self];

    }

     

     

    - (IBAction)textChange:(id)sender {

        self.loginBtn.enabled = (self.accoutField.text.length != 0 && self.passwordField.text.length != 0);

    }

     

    -(void)textChange{

        NSLog(@"%s",__func__);

        //判断输入有没有值

    //    if (self.accoutField.text.length != 0 && self.passwordField.text.length != 0) {

    //        self.loginBtn.enabled = YES;

    //    }else{

    //        self.loginBtn.enabled = NO;

    //        

    //    }

        self.loginBtn.enabled = (self.accoutField.text.length != 0 && self.passwordField.text.length != 0);

        //没有值,禁用登录按钮

    }

     

    - (IBAction)loginBtnClick {

        //判断用户名密码是否正确,只有正确的情况下,才能进行下一个界面

        NSString *accout = self.accoutField.text;

        NSString *password = self.passwordField.text;

        

        //不添加toView参数,提示框是添加在window上,toView代表提示框添加到哪个view

        [MBProgressHUD showMessage:@"正在登录中。。。"];

    //    [MBProgressHUD showMessage:@"正在登录中。。。" toView:self.view];//self.view 就是LoginViewControllerview

    //    [MBProgressHUD showMessage:@"正在登录中。。。" toView:self.navigationController.view];

        //模拟登录有一个等待过程

        //一般登录是网络的请求,而不是本地的请求,很多数据都保存在 云(服务器) 上面去的

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            //登录完成 隐藏提示框

            [MBProgressHUD hideHUD];

    //        [MBProgressHUD hideHUDForView:self.view];

            if ([accout isEqualToString:@"zhangsan"] && [password isEqualToString:@"123"]) {//账号与密码正确

                NSLog(@"账号与密码正确");

                //执行一个segue,就会进入segue所指的控制器

                [self performSegueWithIdentifier:@"toContactsSegue" sender:nil];

                //保存用户账号和密码

                NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

                [defaults setObject:accout forKey:accountKey];

                //只有记住密码开启的状态,才要保存

                if (self.rememberPwdSwitch.isOn) {

                    [defaults setObject:password forKey:passwordKey];

                }

                [defaults synchronize];

                

                

            }else{

                NSLog(@"账号或者密码不正确");

                //给一个错误的提示

                

                [MBProgressHUD showError:@"账号或者密码不正确"];

            }

     

        });

        

    }

     

    // 记录密码开关的值的变化

     

    - (IBAction)rememberPwdSwitchChange {

        //如果记住密码 关闭状态,并且 自动登录为 开启的状态,此时,自动登录 应该为关闭

        if (self.rememberPwdSwitch.isOn == NO && self.autoLoginSwitch.isOn == YES) {

    //        self.autoLoginSwitch.on = NO;

            //添加动画

            [self.autoLoginSwitch setOn:NO animated:YES];

        }

        //保存开关数据

        [self saveSwitchToPreference];

    }

     

    //自动登录开关的值的变化

    - (IBAction)autoLoginSwitchChange {

        //如果 自动登录 开启状态 并且 记住密码 关闭状态,此时,记住密码应该为开启

        if (self.rememberPwdSwitch.isOn == NO && self.autoLoginSwitch.isOn == YES) {

            [self.rememberPwdSwitch setOn:YES animated:YES];

        }

        [self saveSwitchToPreference];

        

    }

     

    -(void)saveSwitchToPreference{

        //保存开关数据

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        [defaults setBool:self.rememberPwdSwitch.isOn forKey:rememberPwdKey];

        [defaults setBool:self.autoLoginSwitch.isOn forKey:autoLoginKey];

       

        [defaults synchronize];

    }

    //使用segue跳转下一个界面之前会调用

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

        

        NSLog(@"%s", __func__);

        NSLog(@"源控制器 %@", [segue sourceViewController]);

        NSLog(@"目标控制器 %@", segue.destinationViewController);

        //可以传递数据给下一个控制器

        //目标控制器

        id destVc = segue.destinationViewController;

        //判断控制器的类型

        if ([destVc isKindOfClass:[ContactsViewController class]]) {

            ContactsViewController *contactsVc = destVc;

            //设置名字属性

            contactsVc.name = self.accoutField.text;

        }

        

    }

     

     

     

    @end

    ContactsViewController.h

    #import <UIKit/UIKit.h>

     

    @interface ContactsViewController : UITableViewController

    @property (nonatomic, copy) NSString *name;

    @end

    ContactsViewController.m

    //

    //  ContactsViewController.m

    //  08.私人通讯录

    //

    //  Created by huan on 16/1/21.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

    /**

     * 保存联系人 使用NSKeyedArcheiver

     * 1.Contact要遵守 NScoding

     * 2.文件保存的路径

     * 3.NSKeyedArcheiver 保存

     * 4.NSKeyedUnArcheiver 读取数据

     */

     

    #import "ContactsViewController.h"

    #import "AddContactViewController.h"

    #import "EditContactViewController.h"

    #import "Contact.h"

    @interface ContactsViewController ()<AddContactViewControllerDelegate, UITableViewDataSource, UITableViewDelegate, EditContactViewControllerDelegate>

     

    @property (nonatomic, strong) NSMutableArray *contacts;

    /**

     * 联系人数据保存的路径

     */

    @property (nonatomic, copy) NSString *contactPath;

     

    @end

     

    @implementation ContactsViewController

     

    -(NSString *)contactPath{

        if (!_contactPath) {

            NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

            _contactPath = [doc stringByAppendingPathComponent:@"contacts.archiver"];

        }

        return _contactPath;

    }

    -(NSMutableArray *)contacts{

        if (!_contacts) {

            //先从沙盒获取数据

            _contacts = [NSKeyedUnarchiver unarchiveObjectWithFile:self.contactPath];

            //程序第一次使用,沙盒没有联系人数据

            if (!_contacts) {

                _contacts = [NSMutableArray array];

            }

        }

        return _contacts;

    }

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view.

        //设置标题

        self.title = [NSString stringWithFormat:@"%@的联系人",self.name];

        

        NSLog(@"%@", self.contactPath);

        ///Users/huan/Library/Developer/CoreSimulator/Devices/37683403-6248-4A9A-863A-53CB9C1361FD/data/Containers/Data/Application/28527B3B-9CCB-4DA4-B3FE-45A8958805EC/Documents/contacts.archiver

        //懒加载中 那个Yes改为NO ~/Documents/contacts.archiver

        

        //在导航栏右边加个按钮

    //    UIBarButtonItem *deleteItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self.navigationItem action:@selector(delete:)];

    //    self.navigationItem.rightBarButtonItems = @[deleteItem, self.navigationItem.rightBarButtonItem];//iOS8上只有这样写,用代码的方式,但是iOS9作出改进,可以在Main.storyboard中添加UIBarButtonItem.

     

    }

    - (IBAction)delete:(id)sender {

        //设置表格的编辑属性

    //    self.tableView.editing = YES;

        //添加动画

    //    [self.tableView setEditing:YES animated:YES];

        [self.tableView setEditing:!self.tableView.editing animated:YES];//点击垃圾按钮可回去。

    }

    #pragma mark 返回表格的编辑状态

    -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{

        if (indexPath.row == 0) {

            return UITableViewCellEditingStyleInsert;

        }

        return UITableViewCellEditingStyleDelete;

    }

    -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{

        NSLog(@"%s", __func__);

        if (editingStyle == UITableViewCellEditingStyleDelete) {

            //获取行

            //删除联系人

            [self.contacts removeObjectAtIndex:indexPath.row];

            //刷新表格

            NSIndexPath *deleteIndex = [NSIndexPath indexPathForRow:indexPath.row inSection:0];

            [self.tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationFade];

            //同步数据

            [NSKeyedArchiver archiveRootObject:self.contacts toFile:self.contactPath];

        }else if (editingStyle == UITableViewCellEditingStyleInsert){

            //添加一个10086联系人

            Contact *contact = [[Contact alloc] init];

            contact.tel = @"10086";

            

            //保存数据,刷新表格

            [self.contacts insertObject:contact atIndex:indexPath.row + 1];

            

            NSIndexPath *insertIndex = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];

            [self.tableView insertRowsAtIndexPaths:@[insertIndex] withRowAnimation:UITableViewRowAnimationFade];

            //同步数据

            [NSKeyedArchiver archiveRootObject:self.contacts toFile:self.contactPath];

        }

    }

     

    #pragma mark 表格的数据

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

        return self.contacts.count;

        

    }

     

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

        

        NSLog(@"%s", __func__);

        

        static NSString *ID = @"ContactCell";

        

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

        //显示数据

        Contact *contact = self.contacts[indexPath.row];

        cell.textLabel.text = contact.name;

        cell.detailTextLabel.text = contact.tel;

        return cell;

        

    }

     

    - (IBAction)logoutBtnClick:(id)sender {

        //注销

        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:nil preferredStyle:UIAlertControllerStyleAlert];

        [alert addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

            //直接返回上一个控制器

            [self.navigationController popViewControllerAnimated:YES];

        }]];

        [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

            

        }]];

     

        //弹出提示框

        [self presentViewController:alert animated:true completion:nil];

        

    }

     

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

        //获取目标控制器

        id destVc = segue.destinationViewController;

        //判断类型

        if ([destVc isKindOfClass:[AddContactViewController class]]) {

            AddContactViewController *addContactVc = destVc;

            addContactVc.delegate = self;

        }else if ([destVc isKindOfClass:[EditContactViewController class]]){

            //1.获取目标控制器

            EditContactViewController *editVc = destVc;

            //2.获取对应索引的联系人

            NSInteger selectedRow = self.tableView.indexPathForSelectedRow.row;

            Contact *contact = self.contacts[selectedRow];

            //3.设置编辑联系人控制器的contact属性

            editVc.contact = contact;

            //4.设置编辑联系人的代理

            editVc.delegate = self;

        }

    }

     

    //-(void)addContactViewController:(AddContactViewController *)addContactVc didSaveContactWithName:(NSString *)name tel:(NSString *)tel{

    //    //刷新表格

    //    Contact *contact = [[Contact alloc] init];

    //    contact.name = name;

    //    contact.tel = tel;

    //    //添加联系人数组

    //    [self.contacts addObject:contact];

    //    //刷新表格

    //    [self.tableView reloadData];

    //    

    //    //隐藏添加联系人的控制器

    //    [self.navigationController popViewControllerAnimated:YES];

    //}

    #pragma mark 添加联系人控制器的代理

    -(void)addContactViewController:(AddContactViewController *)addContactVc didSaveContact:(Contact *)contact{

        //把模型添加到联系人数组

        [self.contacts addObject:contact];

        //刷新

    //    [self.tableView reloadData];

        //局部刷新

        NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.contacts.count - 1 inSection:0];

        [self.tableView insertRowsAtIndexPaths:@[lastPath] withRowAnimation:UITableViewRowAnimationFade];

        //隐藏添加联系人的控制器

        [self.navigationController popViewControllerAnimated:YES];//这句代码也可以写在添加联系人控制器保存按钮操作中,因为官方文档说,谁打开谁销毁。但是也可以写在本控制器刷新前面。这个位置不定,随自己的喜好而定。

        // 同步数据 到沙盒

        [NSKeyedArchiver archiveRootObject:self.contacts toFile:self.contactPath];

        

        

        

    }

     

    #pragma mark 编辑联系人控制器的代理

    -(void)editContactViewController:(EditContactViewController *)editContactVc didFinishedSaveConatct:(Contact *)contact{

        //局部刷新

        //当前刷新的行

        NSInteger row = [self.contacts indexOfObject:contact];

        NSIndexPath *refreshIndex = [NSIndexPath indexPathForRow:row inSection:0];

        [self.tableView reloadRowsAtIndexPaths:@[refreshIndex] withRowAnimation:UITableViewRowAnimationFade];

        //隐藏添加联系人的控制器

        [self.navigationController popViewControllerAnimated:YES];

        

        // 同步数据 到沙盒

        [NSKeyedArchiver archiveRootObject:self.contacts toFile:self.contactPath];

    }

    @end

    AddContactViewController.h

    #import <UIKit/UIKit.h>

    @class AddContactViewController, Contact;

    @protocol AddContactViewControllerDelegate<NSObject>

     

    //-(void)addContactViewController:(AddContactViewController *)addContactVc didSaveContactWithName:(NSString *)name tel:(NSString *)tel;

    //直接返回一个联系人模型

    -(void)addContactViewController:(AddContactViewController *)addContactVc didSaveContact:(Contact *)contact;

     

    @end

    @interface AddContactViewController : UIViewController

     

    @property (weak, nonatomic) id<AddContactViewControllerDelegate>delegate;

     

     

    @end

    //

    //  AddContactViewController.m

    //  08.私人通讯录

    //

    //  Created by huan on 16/1/21.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "AddContactViewController.h"

    #import "Contact.h"

    @interface AddContactViewController ()

    @property (weak, nonatomic) IBOutlet UITextField *nameField;

    @property (weak, nonatomic) IBOutlet UITextField *telField;

     

    @end

     

    @implementation AddContactViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view.

    }

    - (IBAction)saveBtnClick:(id)sender {

        //获取姓名和电话

    //    NSString *name = self.nameField.text;

    //    NSString *tel = self.telField.text;

        

        //通知上一个控制器,完成联系人保存 通过代理

    //    if ([self.delegate respondsToSelector:@selector(addContactViewController:didSaveContactWithName:tel:)]) {

    //        [self.delegate addContactViewController:self didSaveContactWithName:name tel:tel];

    //    }

        if ([self.delegate respondsToSelector:@selector(addContactViewController:didSaveContact:)]) {

            Contact *contact = [[Contact alloc] init];

            contact.name = self.nameField.text;

            contact.tel = self.telField.text;

            

            [self.delegate addContactViewController:self didSaveContact:contact];

        }

        

        //上一个控制器刷新表格

    }

     

     

     

    @end

    EditContactViewController.h

    #import <UIKit/UIKit.h>

    @class Contact, EditContactViewController;

     

    @protocol  EditContactViewControllerDelegate<NSObject>

     

    -(void)editContactViewController:(EditContactViewController *)editContactVc didFinishedSaveConatct:(Contact *)contact;

     

    @end

    @interface EditContactViewController : UIViewController

    //联系人

    @property (nonatomic, strong) Contact *contact;

     

    @property (weak, nonatomic) id<EditContactViewControllerDelegate>delegate;

    @end

    EditContactViewController.m

    //

    //  EditContactViewController.m

    //  08.私人通讯录

    //

    //  Created by huan on 16/1/21.

    //  Copyright © 2016 huanxi. All rights reserved.

    //

     

    #import "EditContactViewController.h"

    #import "Contact.h"

    @interface EditContactViewController ()

    @property (weak, nonatomic) IBOutlet UITextField *nameField;

    @property (weak, nonatomic) IBOutlet UITextField *telField;

    @property (weak, nonatomic) IBOutlet UIButton *saveBtn;

     

    @end

     

    @implementation EditContactViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        //设置文本框默认值

        self.nameField.text = self.contact.name;

        self.telField.text = self.contact.tel;

        

    }

    - (IBAction)editBtnClick:(UIBarButtonItem *)item {

        //1.如果当前是不可用状态 设置文本输入框为可用,按钮可见

    //    if (self.nameField.enabled) {

    //        self.nameField.enabled = NO;

    //    }

        self.nameField.enabled = !self.nameField.enabled;

        self.telField.enabled = !self.telField.enabled;

        self.saveBtn.hidden = !self.saveBtn.hidden;

        

        //2.改变编辑按钮的文字

        if (self.nameField.enabled) {

            item.title = @"取消";

        }else{

            item.title = @"编辑";

        }

        

       }

    - (IBAction)saveBtnClick:(id)sender {

        //3.通过代理通知上一个控制器完成联系人编辑

        if ([self.delegate respondsToSelector:@selector(editContactViewController:didFinishedSaveConatct:)]) {

            //更改联系人的模型

            self.contact.name = self.nameField.text;

            self.contact.tel = self.telField.text;

            //调用代理

            [self.delegate editContactViewController:self didFinishedSaveConatct:self.contact];

        }

     

    }

     

    @end

    Contact.h

    #import <Foundation/Foundation.h>

     

    @interface Contact : NSObject<NSCoding>

     

    @property (nonatomic, copy) NSString *name;

    @property (nonatomic, copy) NSString *tel;

     

    @end

    Contact.m

    #import "Contact.h"

     

    @implementation Contact

    -(void)encodeWithCoder:(NSCoder *)aCoder{

        [aCoder encodeObject:self.name forKey:@"name"];

        [aCoder encodeObject:self.tel forKey:@"tel"];

    }

     

    -(id)initWithCoder:(NSCoder *)aDecoder{

        if (self = [super init]) {

            //一定要赋值

            self.name = [aDecoder decodeObjectForKey:@"name"];

            self.tel = [aDecoder decodeObjectForKey:@"tel"];

        }

        return self;

    }

     

    @end

     

     

     

     

  • 相关阅读:
    Java创建对象的几种方式
    Sqlserver建立Oracle的鏈接服務器
    千万级的大表!MySQL这样优化更好
    ConurrentHashMap和Hashtable的区别
    BTree和B+Tree详解
    为什么MySQL数据库索引选择使用B+树?
    网易跟贴这么火,背后的某个力量不可忽视
    知物由学 | 如何利用人工智能来对抗DDoS攻击?
    揭秘医疗安全防卫战:“我们仍在购买不安全的医疗设备”
    6月第5周业务风控关注 | 《网络安全等级保护条例(征求意见稿)》本周正式发布
  • 原文地址:https://www.cnblogs.com/Lu2015-10-03/p/5164782.html
Copyright © 2020-2023  润新知