KVC(键值编码对)
- 字典转模型
+ (
instancetype
)appInfoWithDict:(
NSDictionary
*)dict {
id obj = [[ self alloc ] init ];
[obj setValuesForKeysWithDictionary :dict];
return obj;
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]];
}];
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 的方法
// 用 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 在日常开发中,绝大多数应该尽量设计的简单!
最好监听的对象属性,不要跨线程修改!如果一定要在后台修改,注意在监听方法中,代码要考虑加锁!
*** 一旦在 kvo 执行的方法中,如果要修改某一个对象的属性,可能会涉及到线程安全问题!
*** 一不小心,就会出现资源抢夺的问题,需要考虑使用互斥锁!
提示: kvo 在日常开发中,绝大多数应该尽量设计的简单!
最好监听的对象属性,不要跨线程修改!如果一定要在后台修改,注意在监听方法中,代码要考虑加锁!
通知中心
特点
解耦合,一对多
/**
要求,程序退出后台后,一旦
"
进入前台
"
,如果当前控制器是活动控制器,需要做一次刷新操作!
*/
//
注册应用程序通知,一旦监听了被激活的通知,就不用再在
AppDelegate
中纠结了!
[[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (becomeActive) name : UIApplicationDidBecomeActiveNotification object : nil ];
[[ 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 ];
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 按照发布者合并
合并的用处:有的时候,可能会接收到多个通知,但是程序只想做出一次响应!
发布者可以利用通知队列,指定监听者工作几次!
*/
/**
通知队列是一个缓冲,可以判断什么时候来发布通知!
利用发送通知的 Style ,同样可以实现简单的异步!
提示:通知中心本身的工作机制没有发生任何变化,变化的是队列的缓冲效果!
NSPostWhenIdle = 1, Idle 发呆,空闲时发布
NSPostASAP = 2, ASAP as soon as possible 尽快
NSPostNow = 3 立即发布
coalesce : 合并 / 聚合
NSNotificationNoCoalescing = 0, 不合并
NSNotificationCoalescingOnName = 1, 按照名称合并
NSNotificationCoalescingOnSender = 2 按照发布者合并
合并的用处:有的时候,可能会接收到多个通知,但是程序只想做出一次响应!
发布者可以利用通知队列,指定监听者工作几次!
*/
//
最后一个参数,指定发布通知的运行循环的模式数组,使用
nil
,就是
默认的运行循环模式