首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSNotification测试类型

NSNotification测试类型
EN

Stack Overflow用户
提问于 2011-09-28 12:46:16
回答 4查看 1.4K关注 0票数 1

我需要检查一个对象是否是NSNotification。仅仅知道它是否是子类是不够的,因为我想区分它是NSNotification还是NSNotification的子类。

因此,为了详细说明,我需要区分以下几点:

  1. NSConcreteNotification
  2. NSNotification的一个子类(但不是NSConcreteNotification)

问题是,NSNotifications实际上是NSConcreteNotifications,而NSConcreteNotification是一个私有类,所以我不能使用它进行测试。

代码语言:javascript
复制
[object isMemberOfClass: [NSNotification class]] // returns NO in both cases
[object isKindOfClass: [NSNotification class]] // returns YES in both cases
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-28 13:45:40

没有理由像您所描述的那样对NSNotification进行子类化。首先,NSNotification已经携带了一个userInfo字典。你可以把你想要的任何数据都放进去。如果你愿意的话,你可以使用分类方法来读和写字典(我一直这么做)。例如,我想要做的一件非常常见的事情是传递某个对象,RNMessage说。因此,我创建了一个类似于这样的类别:

代码语言:javascript
复制
@interface NSNotificationCenter (RNMessage)
- (void)postNotificationName:(NSString *)aName object:(id)anObject message:(RNMessage *)message;
@end

@interface NSNotification (RNMessage)
- (RNMessage *)message;
@end
代码语言:javascript
复制
static NSString * const RNMessageKey = @"message";

@implementation NSNotificationCenter (RNMessage)
- (void)postNotificationName:(NSString *)aName object:(id)anObject message:(RNMessage *)message {
  [self postNotificationName:aName object:anObject userInfo:[NSDictionary dictionaryWithObject:message forKey:RNMessageKey];
}
@end

@implementation NSNotification (RNMessage)
- (RNMessage *)message {
  return [[self userInfo] objectForKey:RNMessageKey];
}

正如@hypercrypt所指出的,您也可以使用关联的引用将数据附加到任何任意对象,而不需要创建ivar,但是对于NSNotification,使用userInfo字典要简单得多。使用NSLog打印通知要容易得多。更容易序列化它们。更容易复制。等。相关的引用是很好的,但是它们确实增加了很多小的角落案例,如果你可以避免的话,你应该避免它。

票数 2
EN

Stack Overflow用户

发布于 2011-09-28 12:54:51

要测试id对象,需要使用NSNotification

代码语言:javascript
复制
[object isMemberOfClass:[NSNotification class]];`

来测试它是否是NSConcreteNotifications使用。

代码语言:javascript
复制
[object isMemberOfClass:NSClassFromString(@"NSConcreteNotifications")];

根据需要将字符串更改为不同类的名称.

然后,您可以将“NSNotification的一个子类(但不是NSConcreteNotification)”的两个检查组合起来。

以下任一项:

代码语言:javascript
复制
if ([object isMemberOfClass:NSClassFromString(@"NSConcreteNotifications")])
{
    // It's a NSConcreteNotifications...
}
else if ([object isKindOfClass:[NSNotification class]])
{
    // It's an NSNotification (or subclass) but not an NSConcreteNotifications
}

代码语言:javascript
复制
if ([object isKindOfClass:[NSNotification class]] && ![object isMemberOfClass:NSClassFromString(@"NSConcreteNotifications")])
{ /* ... */ }

如果要向NSNotification添加属性,则应该查看联想引用

其基本思想是:

代码语言:javascript
复制
static const char objectKey;
- (id)object
{
    return objc_getAssociatedObject(self, &objectKey);
}

- (void)setObject:(id)object
{
    objc_setAssociatedObject(self, &objectKey, object, OBJC_ASSOCIATION_RETAIN);
}
票数 1
EN

Stack Overflow用户

发布于 2011-09-28 13:08:35

听起来真是个坏主意。当您第一次收到通知时,您已经知道它是什么类型了,因为它作为显式参数传递给通知回调方法。考虑将通知存储为另一个对象的强类型属性,或者如果要将通知添加到集合中,则将其插入字典中的适当键下,或者将其传递给其他不保留类型信息的方法,以便以后更容易识别。

创建对私有API的依赖(包括私有类名)将使您的代码更加脆弱,并且更有可能在以后的版本中崩溃。显然,这些课程是保密的原因之一,是为了让苹果的工程师们更容易在他们认为合适的情况下改变这些课程。例如,NSArray和NSMutableArray使用的具体子类在最近发布的SDK中发生了变化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7583414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档