zoukankan      html  css  js  c++  java
  • kvc、kvo、通知

    KVC(NSKeyValueCoding)键值编码

    1.定义:间接访问对象属性(用于字符串表征)的机制,而不是直接通过调用访问器或点语法去访问对象的属性。

    2.KVC把对象属性编码成相应字符串,通过字符串设置访问属性。(等价于将属性变成key和value的形式,类似于字典,注意不要混淆成字典的方法)

    3.当类里面没有定义属性或不知道类里面是什么属性的时候使用KVC。

    4.通过KVC可以访问成员变量(_下划线),但直接访问@"_属性名"(破坏了封装的特性)没有做正确性校验,所以通常@"属性名"。通过KVC也可以设置访问私有成员变量,总的来说可以设置访问所有属性。


    KVO(NSKeyValueObserving)键值监听

    1.定义:当对象属性发生变化,我们能收到一个"通知";起监听属性的作用。

    2.KVO是基于KVC的,NSObject类为所以对象提供一个自动观察机制(也可以自己监听自己)。

    3.步骤:

    • 注册监听对象属性
    • 实现回调方法(当属性发生改变,系统自动调用)
    • 移除

    上下文(context):上文与下文的联系。通过上下文可以传值,是C语言的概念(void *),万能指针可以传任何东西,常用传数组.

    Observer:监听者

    options:有4种可能选择,用|选择多种。


    通知(面对熟悉的人群,代理的话是面对陌生者)

    1.通知一般用于MVC间信息传递,如设置页面app换肤(1对多传值)。

    2.通知发送(NSNotification)

    • name:通知的名字,xxx通知(唯一的)
    • userinfo:内容(用字典存)
    • object:发送者,xxx发送(通常不太关心)

    3.通知中心(NSNotificationCenter):单例,作中转站,统一管理。

    • 注册和移除都是放生在监听者身上。
    • 通知发送写在其它类。

    4.作用:通知用于2各不相关的类之间传值。

    5.特点:广播式(1个类到通知中心向多个监听者传播)

    6.目标-动作机制

    目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见”插座变量”部分)
    的形式保有其动作消息的目标。
    动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法。
    程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制。


    kvc&&kvo

    Teacher.h

    #import <Foundation/Foundation.h>
    
    @interface Teacher : NSObject
    {
        NSString *_name;
        int _age;
        
        @private
        NSString *count;
    }
    
    @property(nonatomic,retain)NSString *name;
    @property(nonatomic,assign)int age;
    
    
    @end

    Teacher.m

    #import "Teacher.h"
    
    @implementation Teacher
    @synthesize name = _name,age = _age;
    
    
    -(id)init//因为当自己监听自己,所以在这里写
    {
        self = [super init];
        if (self)
        {
            //注册监听name属性
            [self addObserver:self
                   forKeyPath:@"name"
                      options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld//枚举
                      context:@"123"];//数组传多个值
            //注册监听age属性。。。
            
        }
        return self;
    }
    
    //当属性发生变时候,此方法自动调用
    -(void)observeValueForKeyPath:(NSString *)keyPath
                         ofObject:(id)object
                           change:(NSDictionary *)change
                          context:(void *)context
    {
        NSLog(@"keyPath = %@",keyPath);
        NSLog(@"object = %@",object);
        NSLog(@"change = %@",change);
        NSLog(@"context = %@",context);
    }
    
    
    
    -(void)dealloc
    {
        [_name release];
        [count release];
        
        
        [super dealloc];
    }
    
    @end

    AppDelegate.m

    //Teacher *t = [[Teacher alloc]init];
        
        /*
        [t setValue:@"jobs" forKey:@"_name"];
        NSLog(@"%@",[t valueForKey:@"_name"]);
        
        [t setValue:[NSNumber numberWithInt:18] forKey:@"_age"];
        NSLog(@"%@",[t valueForKey:@"_age"]);
        
        //
        [t setValue:@"28" forKey:@"count"];
        NSLog(@"%@",[t valueForKey:@"count"]);
        */
        
        /*
        //kvo
        t.name = @"obanma";
        t.name = @"jobs";
        */

    通知

    Student.h

    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject
    {
        NSString *_name;
    }
    @property(nonatomic,retain)NSString *name;
    
    
    @end

    Student.m

    #import "Student.h"
    
    @implementation Student
    @synthesize name = _name;
    
    
    -(id)init
    {
        self = [super init];
        if (self)
        {
            //到通知中心注册
            NSNotificationCenter *center = nil;
            center = [NSNotificationCenter defaultCenter]; //获取通知中心,唯一的
            
            //监听者注册
            [center addObserver:self      //监听者
                       selector:@selector(goHome:)
                           name:@"GO_HOME_NOTIONIFICATION"//唯一
                         object:nil];    //发送者
            
            
        }
        return self;
    }
    
    -(void)goHome:(NSNotification *)aNoti//target-ation机制
    {
        //收到通知的内容
        NSDictionary *dic = [aNoti userInfo];
        NSString *date = [dic valueForKey:@"date"];
        NSString *time = [dic valueForKey:@"time"];
        NSLog(@"%@ go home at %@,%@",self.name,date,time);
    }
    
    -(void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:@"GO_HOME_NOTIONIFICATION"
                                                      object:nil];
        
        [_name release];
        [super dealloc];
    }
    @end

    Master.h

    #import <Foundation/Foundation.h>
    
    @interface Master : NSObject
    {
        NSString *_name;
    }
    @property(nonatomic,retain)NSString *name;
    
    -(void)furlough;
    @end

    Master.m

    #import "Master.h"
    
    @implementation Master
    @synthesize name = _name;
    
    //发送
    -(void)furlough
    {
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        //字典内容
        NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:@"24",@"date",@"6:00",@"time", nil];
        
        
        [center postNotificationName:@"GO_HOME_NOTIONIFICATION" object:nil userInfo:dic];
    }
    
    -(void)dealloc
    {
        [_name release];
        [super dealloc];
    }
    @end

    AppDelegate.m

    //通知
        Master *s = [[Master alloc]init];
        
        Student *s1 = [[Student alloc]init];
        s1.name = @"jobs";
        
        Student *s2 = [[Student alloc]init];
        s2.name = @"bill";
        
        [s furlough];

     kvo手动监听属性和自动监听属性

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self addObserver:self forKeyPath:@"num" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    - (IBAction)changeValueAction:(id)sender {
        //手动通知在需要改变值num变量的地方
        [self willChangeValueForKey:@"num"];
        self.num = 2;
        [self didChangeValueForKey:@"num"];
    }
    
    //当设置为手动的时候如果不调用willChangeValueForKey:didChangeValueForKey:的情况,observeValueForKeyPath:不会调用
    +(BOOL)automaticallyNotifiesObserversForKey:(NSString *)key{
        //设置是否自动监听属性
        if ([key isEqualToString:@"num"]) {
            return NO;//手动监听num
        }
        return [super automaticallyNotifiesObserversForKey:key];
    }
    
    //系统监听属性变化方法
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        if ([keyPath isEqualToString:@"num"
            ]) {
            NSInteger targetNum = [[change objectForKey:NSKeyValueChangeNewKey]integerValue];
            NSLog(@"num = %ld",targetNum);
        }else{
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    
    -(void)dealloc{
        [self removeObserver:self forKeyPath:@"num" context:nil];
    }
  • 相关阅读:
    configparser模块
    xml文件解析
    shutil模块 + shelve模块 二合一版
    hashlib模块
    subprocess模块和sys模块
    re模块
    os模块
    random模块
    time模块、datetime模块讲解
    洛谷P3414 SAC#1
  • 原文地址:https://www.cnblogs.com/huen/p/3529947.html
Copyright © 2011-2022 走看看