iOS中 KVC\KVO和通知三者之间的小结


KVC(键值编码对)
  • 字典转模型
+ ( instancetype )appInfoWithDict:( NSDictionary *)dict {
   
id obj = [[ self alloc ] init ];
    [obj
setValuesForKeysWithDictionary :dict];
   
return obj;
}
    // 使用 Capacity 的效率更高!
   
NSMutableArray *arrayM = [ NSMutableArray arrayWithCapacity :array. count ];
   
// 用块代码遍历数组,效率比 forin
    [array
enumerateObjectsUsingBlock :^( id obj, NSUInteger idx, BOOL *stop) {
        [arrayM
addObject :[ AppInfo appInfoWithDict :obj]];
    }];
   
    _appList = [arrayM copy];

其中 setValuesForKeysWithDictionary :方法可以批量将字典中的元素赋值到对应名称的self成员变量中,字典中有几个键值对,就可以有几个与key相同的成员变量,要求字典键值名称必须与模型成员名称相同,便可自动复制。字典中的键值对可不全部显示出来。
KVC还可以查找路径
NSArray *array = [ persons valueForKeyPath: @“name”] KVC按照路径取值时,如果对象不包含指定对象时,会自动进入对象内部,查找对象属性。

  • 为tableView增加索引
- ( NSArray *)sectionIndexTitlesForTableView:( UITableView *)tableView
{
    // 使用KVC可以一次性将同一key的键值整理成一个集合并返回
    return [ self . totalCars valueForKeyPath : @"title" ];
}

  • 动态读取( OC 语言是动态语言,KVC 间接设置数值的方法!在程序执行的时候,动态设置或者获取对象的属性!)
    // person 对象
   
// kvc setValuesWithDict 来个模型设置数值,字典转模型
   
Person *p = [ Person personWithDict : @{ @"name" : @"laofang" , @"age" : @18} ];

   
// 以下两行代码知道就行,不建议自己这么写!
    [p
setValue : @"Banzhang" forKeyPath : @"title" ];
    [p
setValue : @"1.6" forKeyPath : @"height" ];
   
   
// 要把自定义对象发送到服务器,模型转字典
   
// dictionaryWithValuesForKeys 同样是 KVC 的方法
    // 参数:指定要转换成字典的属性名称数组


KVO(键值观察对,观察者模式)

    // 使用 KVO 添加监听,监听 _mainV frame 标识发生改变
    [_mainV addObserver : self forKeyPath : @"frame" options : NSKeyValueObservingOptionNew context : nil ];

// 当监听成立时自动调用下面方法( 特点:无论监听了多少个键值,都会统一调用一个方法!)
- ( void )observeValueForKeyPath:( NSString *)keyPath ofObject:( id )object change:( NSDictionary *)change context:( void *)context

// 注销监听事件

    [ _mainV removeObserver : self forKeyPath : @"frame" ];
  • 注意点
  •  *  解决二级联动的BUG,同一对象,同一键值对,可以添加多次监听,添加几次,就要注销几次
  • // 定义两个bool值用来记录是否正在被监听
  • 注意点:KVO是同步的还是异步的? -同步的!为了保证属性变化时,及时作出响应!,通知中心也是同步的,需要所有的监听者做出相应.

陷阱:一旦在后台线程修改监听对象的键值,会在相同线程调用 kvo 的方法
    ***
一旦在 kvo 执行的方法中,如果要修改某一个对象的属性,可能会涉及到线程安全问题!
    ***
一不小心,就会出现资源抢夺的问题,需要考虑使用互斥锁!
 
 
提示: kvo 在日常开发中,绝大多数应该尽量设计的简单!
 
最好监听的对象属性,不要跨线程修改!如果一定要在后台修改,注意在监听方法中,代码要考虑加锁!



通知中心
特点

解耦合,一对多


/**
  要求,程序退出后台后,一旦 " 进入前台 " ,如果当前控制器是活动控制器,需要做一次刷新操作!
 */
    // 注册应用程序通知,一旦监听了被激活的通知,就不用再在 AppDelegate 中纠结了!
    [[
NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (becomeActive) name : UIApplicationDidBecomeActiveNotification object : nil ];
    // 注册通知
    [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(test:)name:@"btn"object:nil];
    // 销毁通知
    [[ NSNotificationCenter defaultCenter ] removeObserver : self name : @"touch" object : nil ];
    // 发送通知
    [[ NSNotificationCenter defaultCenter ] postNotificationName : @"touch" object : @"hello" userInfo : dic ];
  • 通知队列
    // 通知队列,创建队列 , 利用队列的发送模式可以实现类似异步的效果。
   
NSNotification *noti = [ NSNotification notificationWithName : @"btn" object : nil ];
    [[
NSNotificationQueue defaultQueue ] enqueueNotification :noti postingStyle : 2 ];
    [[NSNotificationQueuedefaultQueue]enqueueNotification:notipostingStyle:2coalesceMask:1forModes:nil];
    // 入队
   
/**
    
通知队列是一个缓冲,可以判断什么时候来发布通知!
    
利用发送通知的 Style ,同样可以实现简单的异步!
    
提示:通知中心本身的工作机制没有发生任何变化,变化的是队列的缓冲效果!
    
     NSPostWhenIdle = 1,    Idle
发呆,空闲时发布
     NSPostASAP = 2,        ASAP as soon as possible
尽快
     NSPostNow = 3         
立即发布
    
     coalesce :
合并 / 聚合
     NSNotificationNoCoalescing = 0,       
不合并
     NSNotificationCoalescingOnName = 1,   
按照名称合并
     NSNotificationCoalescingOnSender = 2  
按照发布者合并
    
    
合并的用处:有的时候,可能会接收到多个通知,但是程序只想做出一次响应!
    
发布者可以利用通知队列,指定监听者工作几次!
     */
    // 最后一个参数,指定发布通知的运行循环的模式数组,使用 nil ,就是 默认的运行循环模式



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值