通过FMDB 写了一个本地 即使通讯录和消息存储的数据库,想实现如果当本地数据库数据更新的时候,通知其他相关UI同步;
聊天中 设计相关ui较多,添加消息后,通讯录最新消息以及消息UI都需要修改,或者当前用户的昵称更改了,需要修改的地方很多,此时如果使用代理,怎么办呢?
这里需要用到弱引用,
当我们如果用一个NSArray 存储对象后,会对对象强引用,导致无法释放,不能再 dealloc中 removeDelegate;因为强引用,所以无法这样,还需要手动再去管理,
但是使用弱引用,就可以简单的引用,引用计数不变
NSMapTable 对应 NSDictionary ; NSHashTable 对应 NSSet ; NSPointerArray 对应 NSArray .它们提供了对象内存管理的方式.
最后的使用效果就是
- (void)dealloc {
[[ChartDatabaseManager share] deleteDelegate:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
[[ChartDatabaseManager share] addDelegate:self];
}
addDelegate 以及 deleteDelegate
分别是里面数组 NSPointerArray 对应的 添加和删除
至于如何 通过manager 通知代理执行相关方法
两种方式:
一、直接遍历NSPointerArray 里的delegate 执行相应
// 不用消息转发 也可以实现
- (void)addressListUpdate {
for (id delegate in _delegates) {
if (delegate && [delegate respondsToSelector:@selector(addressListUpdate)]) {
[delegate performSelector:@selector(addressListUpdate)];
}
}
}
二、通过消息转发
//消息转发 上述方法没有实现的情况下
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
NSMethodSignature *signature = [super methodSignatureForSelector:selector];
if (signature) {
return signature;
}
[_delegates addPointer:NULL];
[_delegates compact];
if (self.silentWhenEmpty && _delegates.count == 0) {
return [self methodSignatureForSelector:@selector(description)];
}
for (id delegate in _delegates) {
if (!delegate) {
continue;
}
signature = [delegate methodSignatureForSelector:selector];
if (signature) {
break;
}
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
SEL selector = invocation.selector;
BOOL responseed = NO;
for (id delegate in _delegates) {
if (delegate && [delegate respondsToSelector:selector]) {
[invocation invokeWithTarget:delegate];
responseed = YES;
}
}
if (!responseed && !self.silentWhenEmpty) {
[self doesNotRecognizeSelector:selector];
}
}