Objective-C: Add an observer to an NSMutableDictionary that gets notified when count reaches 0
I would like to be notified, when an NSMutableDictionary's count reaches 0. Is that possible without extending NSMutableDictionary (which I heard you should not really do)?
Could I e.g. have a category th开发者_StackOverflow社区at mimicks remove methods by calling the original ones while checking whether count is 0? Or is there maybe a simpler way. I tried KVO, but that did not work...
Any help is appreciated.
Joseph
When working with Dictionaries and other "class cluster" objects, the easiest way to "subclass" them is to create a subclass and wrap it around an existing object of the same type:
@interface MyNotifyingMutableDictionary:NSMutableDictionary {
NSMutableDictionary *dict;
}
// these are the primitive methods you need to override
// they're the ones found in the NSDictionary and NSMutableDictionary
// class declarations themselves, rather than the categories in the .h.
- (NSUInteger)count;
- (id)objectForKey:(id)aKey;
- (NSEnumerator *)keyEnumerator;
- (void)removeObjectForKey:(id)aKey;
- (void)setObject:(id)anObject forKey:(id)aKey;
@end
@implementation MyNotifyingMutableDictionary
- (id)init {
if ((self = [super init])) {
dict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSUInteger)count {
return [dict count];
}
- (id)objectForKey:(id)aKey {
return [dict objectForKey:aKey];
}
- (NSEnumerator *)keyEnumerator {
return [dict keyEnumerator];
}
- (void)removeObjectForKey:(id)aKey {
[dict removeObjectForKey:aKey];
[self notifyIfEmpty]; // you provide this method
}
- (void)setObject:(id)anObject forKey:(id)aKey {
[dict setObject:anObject forKey:aKey];
}
- (void)dealloc {
[dict release];
[super dealloc];
}
@end
I tried with my first ever category, which seems to work:
NSMutableDictionary+NotifiesOnEmpty.h
#import <Foundation/Foundation.h>
@interface NSMutableDictionary (NotifiesOnEmpty)
- (void)removeObjectForKeyNotify:(id)aKey;
- (void)removeAllObjectsNotify;
- (void)removeObjectsForKeysNotify:(NSArray *)keyArray;
- (void)notifyOnEmpty;
@end
NSMutableDictionary+NotifiesOnEmpty.m
#import "Constants.h"
#import "NSMutableDictionary+NotifiesOnEmpty.h"
@implementation NSMutableDictionary (NotifiesOnEmpty)
- (void)removeObjectForKeyNotify:(id)aKey {
[self removeObjectForKey:aKey];
[self notifyOnEmpty];
}
- (void)removeAllObjectsNotify {
[self removeAllObjects];
[self notifyOnEmpty];
}
- (void)removeObjectsForKeysNotify:(NSArray *)keyArray {
[self removeObjectsForKeys:keyArray];
[self notifyOnEmpty];
}
- (void)notifyOnEmpty {
if ([self count] == 0) {
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationDictionaryEmpty object:self];
}
}
@end
Don't know if that is an elegant solution, but it seems to work okay.
精彩评论