1.KVC底層是通過runtime對method和value操作
比如說如下的一行KVC的代碼:
[sit setValue:@"sitename" forKey:@"name"];
就會被編譯器處理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (site->isa,sel);
method(site, sel, @"sitename", @"name”);
前兩步就是通過rt找到method,最后一步更新值;
2.KVO就是基于KVC添加了消息通知,觀察者模式;
3.KVB?兩個基本方法
1:為對象添加觀察者OBserver
addObserver:forKeyPath:options:context:
2:觀察者OBserver收到信息的處理函數(shù)
observeValueForKeyPath:ofObject:change:context:
以下是使用Demo
1.直接在VC里面操作屬性/變量(不推薦耦合度不好)
@property (nonatomic,strong) NSString *str1;
在viewDidLoad加入:
[self addObserver:self forKeyPath:@"str1" options:NSKeyValueObservingOptionNew context:nil];//第一步
[self setValue:@"草泥馬KVO" forKey:@"str1”];//第二步
//回調(diào)方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if([keyPath isEqualToString:@"count"]){
NSLog(@"count : %@",[change valueForKey:@"new"]);
}
if([keyPath isEqualToString:@"str1"]){
NSLog(@"str1: %@",[change valueForKey:@"new"]);
}
}
在第一步添加注冊元素@“str1",然后第二步改變其值,此時第三步回調(diào)方法就會響應(yīng);
2.自定義類?OberserClass
#import
@interface OberserClass : NSObject
@property (nonatomic,assign) int count;
@end
#import "OberserClass.h"
@implementation OberserClass
@end
簡單添加一個屬性,什么也不做。然后在ViewDidLoad加入以下代碼:
cls = [[OberserClass alloc]init];//cls必須是成員變量,不能是局部變量
[cls addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew context:nil];
[cls setValue:@"456" forKey:@"count"];
執(zhí)行到最后一步observeValueForKeyPath就會收到通知,處理@“count"
3.自定義類內(nèi)部處理
和第二種不一樣的是,在@implementation添加如下代碼:
- (void)setCount:(int)count{
_count = count;
[self? addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if([keyPath isEqualToString:@"count"]){
NSLog(@"count is :");
}
}
@end