Objective-C:向 NSMutableDictionary 添加一个观察者,当计数达到 0 时该观察者会收到通知

发布于 2024-09-12 07:09:34 字数 216 浏览 6 评论 0原文

当 NSMutableDictionary 的计数达到 0 时,我希望收到通知。是否可以在不扩展 NSMutableDictionary 的情况下实现这一点(我听说你不应该这样做)?

例如,我是否可以有一个类别,通过调用原始方法同时检查 count 是否为 0 来模仿删除方法?或者有没有更简单的方法。我尝试了 KVO,但是没有用...

任何帮助都是值得赞赏的。

约瑟夫

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

饭团 2024-09-19 07:09:34

当使用字典和其他“类簇”对象时,对它们进行“子类化”的最简单方法是创建一个子类并将其包装在相同类型的现有对象周围:

@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

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
惜醉颜 2024-09-19 07:09:34

我尝试使用我的第一个类别,这似乎有效:

NSMutableDictionary+NotifyOnEmpty.h

#import <Foundation/Foundation.h>

@interface NSMutableDictionary (NotifiesOnEmpty)
- (void)removeObjectForKeyNotify:(id)aKey;
- (void)removeAllObjectsNotify;
- (void)removeObjectsForKeysNotify:(NSArray *)keyArray;
- (void)notifyOnEmpty;
@end

NSMutableDictionary+NotifyOnEmpty.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

不知道这是否是一个优雅的解决方案,但它似乎工作正常。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文