KVC KVO 通知 委托模式 小结

1、kvc

kvc很简单就是声明属性时不添加属性的setter方法和getter方法,而用kvc专有的方法进行赋值和取值
例子如下:

@interface Student : NSObject

    //声明时不加@property关键字
{
NSString *_name;
NSInteger _age;
}


@end
//重写description方法
@implementation Student

- (NSString *)description {


    return [NSString stringWithFormat:@"name is %@,age is %ld",_name,_age];

}

//在 main 函数中执行以下代码
     Student *stu = [Student new];
        [stu setValue:@"zsz" forKey:@"_name"];
        //这里要注意封装基本数据类型,因为要传入的只能是对象
         [stu setValue:[NSNumber numberWithInteger:22] forKey:@"_age"];
        NSLog(@"%@",[stu description]);

2、KVO

基于kvc的一种技术…
分为以下3步
(1)注册成为观察者
(2)观察者定义kvo的回调
(3)移除观察者

//
//  StudentObserver.h
//  阶段小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//


@interface StudentObserver : NSObject


@property (nonatomic,strong)Student *student;

//注册成为观察者的方法
- (id)addObserver;


@end

如上,把要进行观察的对象传入观察者里面作为观察者的一个属性(传入的这个对象一定要遵循kvc),顺便声明一个注册成为观察者的方法;

//
//  StudentObserver.m
//  阶段小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//



@implementation StudentObserver
//以下是注册成为观察者的方法,

- (id)addObserver {
//注意这下面注册时是调用被观察者对象的方法。。。
        [self.student addObserver:self forKeyPath:@"_name" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];

[self.student addObserver:self forKeyPath:@"_age" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];


return self;
}
//以下是重写的回调方法,一旦要观察的对象的属性发生变化,就执行相应的方法

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {


if ([keyPath isEqualToString:@"_name" ] ) {
    NSString *oldName = [change objectForKey:NSKeyValueChangeOldKey];
    NSString *newName = [change objectForKey:NSKeyValueChangeNewKey];
    NSLog(@"oldName = %@,newName = %@",oldName,newName);
} else if ([keyPath isEqualToString:@"_age"]) {

    NSString *oldAge = [change objectForKey:NSKeyValueChangeOldKey];
    NSString *newAge = [change objectForKey:NSKeyValueChangeNewKey];
    NSLog(@"oldAge = %@,newName = %@",oldAge,newAge);
}


}   

    //以下是移除观察者
- (void)dealloc {

[self.student removeObserver:self forKeyPath:@"_name"];
[self.student removeObserver:self forKeyPath:@"_age"];

}
//以下代码是在主函数中调试kvo的代码

 StudentObserver *aStuOb = [StudentObserver new];
        aStuOb.student = stu;
        aStuOb = [aStuOb addObserver];
        [stu setValue:@"zsz2" forKey:@"_name"];
            [stu setValue:[NSNumber numberWithInteger:18] forKey:@"_age"];

3、通知

步骤:

1、要发送通知的对象要先声明实现一个方法,可以到通知中心发送一个通知

//.h文件中
    @interface Center : NSObject
- (void)sentMessage;
@end
//.m文件中

@implementation Center

- (void)sentMessage {

//创建一个通知对象,在通知中心 把通知发出去
NSNotification *notification = [[NSNotification alloc] initWithName:@"Message" object:self userInfo:[NSDictionary dictionaryWithObject:@"发送了通知" forKey:@"key1"]];
[[NSNotificationCenter defaultCenter] postNotification:notification];

//简便写法
//    [[NSNotificationCenter defaultCenter] postNotificationName:@"Message" object:self userInfo:[NSDictionary dictionaryWithObject:@"我发送了通知" forKey:@"key1"]];

}
@end

2、要接收通知的对象,要声明实现一个接收通知的方法,并实现一个回调方法,最后移除通知

//
//  People.h
//  通知小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface People : NSObject
-(void)login;//注册监听者接收通知的方法
- (void)aMethod:(NSNotification *)notifi;//回调方法


@end

//
//  People.m
//  通知小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//

#import "People.h"

@implementation People


- (void)login {

    //先到通知中心注册监听者,说明可以接收怎样的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(aMethod:) name:@"Message" object:nil];

}


//接收到通知要执行的方法
- (void)aMethod:(NSNotification *)notifi {

    NSDictionary *dict = [notifi userInfo];//从通知的字典中获取通知内容
    NSLog(@"我接收到了它    %@",[dict objectForKey:@"key1"]);
}

//移除通知
- (void)dealloc {

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"Message" object:nil];
}

@end

通知与kvo的区别:
KVO只能监听属性的变化,通过NSString类型的属性名来实现,实现了自动监听,当属性值发生变化时,会自动通知观察者,不用在添加代码了。但是观察者得持有被观察者的引用,一边在观察者对象中调用被观察对象的方法,耦合性太高,不利于代码维护。。。。。
通知 就比较灵活,可以监听的内容不局限于属性的变化,还可以对多种多样的状态变化进行监听,(比如,一旦属性发生变化就直接发送一个通知就好。一旦调用了哪个方法也可以发送一个通知,把这个通知在那个方法里调用)缺点是想:需要被观察者自己手动发送通知

利用协议 的 委托模式

建立两个类student和waiter类,waiter遵守协议,如果学生忙就要送餐给学生。如果学生不忙就不用送,学生自己拿

直接通过例子来看

//
//  Sent.h
//  委托模式小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol Sent <NSObject>//这是一个送餐协议
- (void)sent;
- (void)noSent;
@end

    //
    //  Waiter.h
    //  委托模式小结
    //
    //  Created by 5005 on 15/8/9.
    //  Copyright (c) 2015年 tmr. All rights reserved.
    //

    #import <Foundation/Foundation.h>
    #import "Sent.h"
    @interface Waiter : NSObject <Sent>//waiter遵守这个协议

    @end
//
//  Waiter.m
//  委托模式小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//

#import "Waiter.h"

@implementation Waiter//waiter实现了这个协议的方法
- (void)sent {

    NSLog(@"学生忙,要送餐");
}

- (void)noSent {

    NSLog(@"学生不忙,自己拿");
}
@end

//
//  Student.h
//  委托模式小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Sent.h"
@interface Student : NSObject
@property (nonatomic,strong)id <Sent>delegate;//这里定义一个代理,一定要遵守这个送餐协议
@property (nonatomic,assign)BOOL busy;//
- (void)isBusy;//是否忙调用传入的代理的协议的方法,相当回调方法
@end
//
//  Student.m
//  委托模式小结
//
//  Created by 5005 on 15/8/9.
//  Copyright (c) 2015年 tmr. All rights reserved.
//

#import "Student.h"

@implementation Student
-(void)isBusy {//通过条件判断使用传入代理的哪个方法
    if (self.busy) {
         [self.delegate sent];
    } else {
        [self.delegate noSent];
    }

}
@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值