Цель-C: добавить наблюдателя в NSMutableDictionary, который получает уведомление, когда счетчик достигает 0 - PullRequest
1 голос
/ 30 июля 2010

Я хотел бы получить уведомление, когда счетчик NSMutableDictionary достигает 0. Это возможно без расширения NSMutableDictionary (что я слышал, вы не должны делать)?

Могу ли я, например, иметь категорию, которая имитирует методы удалениявызывая оригинальные, проверяя, равно ли число 0?Или есть, возможно, более простой способ.Я пытался KVO, но это не сработало ...

Любая помощь приветствуется.

Джозеф

Ответы [ 2 ]

1 голос
/ 30 июля 2010

При работе со словарями и другими объектами «кластера классов» самый простой способ их «подкласса» - создать подкласс и обернуть его вокруг существующего объекта того же типа:

@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
1 голос
/ 30 июля 2010

Я пытался с моей первой в категории, которая, кажется, работает:

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

Не знаю, изящное ли это решение, но, похоже, оно работает нормально.

...