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按照路径取值时,如果对象不包含指定对象时,会自动进入对象内部,查找对象属性。
- (
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
,就是
默认的运行循环模式