zoukankan      html  css  js  c++  java
  • [oc学习日记]kvc,kvo和通知

    KVC键值对编码

    kvc键值对编码就是在对象没有声明属性(毕竟能用点方法没几个人会再去用kvc),成员变量没有公有化,并且没有写描述方法时使用的一种给成员变量或者属性赋值的一种方式。

    例如:

            //我们创建了一个学生类,并将其实例化
            Student *stu = [[Student alloc]init];
            //给学生队形的name成员变量使用kvc赋值
            [stu setValue:@"ss" forKey:@"name"];
            //取出使用键值对进行赋值了的name成员变量的值
            NSLog(@"%@",[stu valueForKey:@"name"]);

     

    如果此时学生有一本书,并且这个书有名字,那我们该怎么在学生对象中输出这本书的名字呢

            //首先要用下面这个方法给书的名字进行赋值
            [stu setValue:@"语文" forKeyPath:@"book.name"];
            //而且要在学生类中定义一个book类的对象,而且这个变量的name的成员变量必须要添加@public或者定义属性,否则学生类中无法访问book的name
            Book *book ;

    KVO键值观察

    没有kvc就没有kvo,当对象属性或者成员变量的值通过kvc发生变化时,kvo就会观察到值的变化,并且做出反应

    kvo有三个步骤:

    要另外写一个观察者类

    1.注册成为观察者

    1 -(void)registerWatch{
    2     //第一个参数:被观察的对象,第二个参数:观察者的对象,第三个参数:被观察的对象的属性或者变量名,第四个参数:接收到变化的通知时,给我们展示的内容
    3     [_stu addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    4 }

    2.重写observeValueForKeyPath方法

    1 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    2     NSLog(@"%@",keyPath);//(被观察者)发生改变的变量或属性名
    3     
    4     NSLog(@"%@",object);//被观察者
    5     NSLog(@"%@",change);//属性或变量改变前后的值(字典)new:改变后   old:改变前
    6     NSLog(@"%@",[change objectForKey:@"new"]);
    7 }

    3.移除kvo

    -(void)dealloc{
        //移除kvo
        [_stu removeObserver:self forKeyPath:@"name"];
    }

    如何使用kvo:

    在主函数中实例化一个观察者对象,将其注册成为观察者对象

    如果被观察者的成员变量活着属性发生变化就会根据observeValueForKeyPath方法输出相应内容

    通知

    通知模式就是通知中心发送信息,如果观察者(接受信息者)监听(接收)到了信息,那么会做出一定的回应

    通知模式的使用:

    1. 注册通知

    -(void)addNotifi{
        //在通知中心注册通知:第一个参数,代表通知接收对象,第二个参数:代表接收到通知后调用的方法,第三个参数:代表通知的名字 最后一个参数不用管,直接给nil
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receive:) name:@"Notifi" object:nil];
    }

     2.接收到信息作出反应的方法

    //如果通知包含参数,那么方法定义时,需要一个通知的对象作为参数
    -(void)receive:(NSNotification *)note{
           NSLog(@"收到通知");
    //    NSLog(@"%@",note.object);//此处的note.object就代表发送通知时传过来的信息
        
    //    传过来的是什么类型的参数,我们就用什么类型的变量进行处理
    //    NSDictionary *dic = note.object;
    //    NSLog(@"--%@",dic);
        
        NSLog(@"%@",note.userInfo);//此处的userinfo就代表发送通知时,传过来的userinfo
    }

    3.移除通知

    -(void)dealloc{
        //移除通知,避免消耗内存 ,第一个参数,代表之前注册的通知接收对象,第二个参数,代表注册时写的通知名字
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"Notifi" object:nil];
    }

    通知模式的使用

    在main函数中

            Student *stu = [Student new];
            //将学生对象添加为观察者(监听者)
            [stu addNotifi];
            
            //第一个参数:传入通知名字,告诉通知中心,给哪个通知发消息,注意,此处的名字要与之前注册的名字完全一致,第二个参数,代表发送通知时附带的参数或信息
            NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"1",@"a", nil];
    //        [[NSNotificationCenter defaultCenter] postNotificationName:@"Notifi" object:dic];
            
            //userInfo是通知的一个变量,也可以用来传参
            [[NSNotificationCenter defaultCenter]postNotificationName:@"Notifi" object:nil userInfo:dic];

    kvo与通知模式的比较:

    通知模式是由通知中心发送(不可控),kvo是由kvc进行赋值(可控)

  • 相关阅读:
    Gradle中的buildScript,gradle wrapper,dependencies等一些基础知识
    在liferay 7中如何删除service builder已经生成的数据库table
    settings.gradle与build.gradle有什么区别
    如何建一个Liferay 7的theme
    如何在IDE的开发环境中启动Studio和本地build出一个product
    Lunix文件的读写权限问题
    liferay 7用OSGi的方式修改默认权限
    Liferay 7 module项目的依赖问题
    城市选择
    2016/04/26 流程 数据库lcdb 四个表 1,用户表users 2,流程表(设定有哪些流程)liucheng 3,流程发起者表(记录谁发起到哪里) 4,流程经过的人员表 flowpath (order排序)
  • 原文地址:https://www.cnblogs.com/0error/p/4558604.html
Copyright © 2011-2022 走看看