views:

187

answers:

2

Hi there,

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 that 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

A: 

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.

Joseph Tura
A: 

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
MrO