如果我想添加类型属性,是否将NSNotification子类化为正确的路径?

Und*_*ion 10 inheritance cocoa objective-c nsnotification class-cluster

我正在尝试子类NSNotification.

Apple的文档NSNotification陈述如下:

NSNotification是一个没有实例变量的类集群.因此,你必须继承NSNotification和覆盖原始的方法 name,objectuserInfo.您可以选择任何您喜欢的指定初始值设定项,但请确保您的初始化程序不会调用 (via )NSNotification的实现. 并不意味着直接实例化,它的 方法引发了异常.init[super init]NSNotificationinit

但这对我来说并不清楚.我应该创建这样的初始化器吗?

-(id)initWithObject:(id)object
{
    return self;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ong 14

子类化NSNotification是一种非典型的操作.我想我在过去几年里只看过一次或两次.

如果您希望将通知与通知一起传递,那就是该userInfo属性的用途.如果您不喜欢userInfo直接访问内容,可以使用类别来简化访问:

@interface NSNotification (EasyAccess)

@property (nonatomic, readonly) NSString *foo;
@property (nonatomic, readonly) NSNumber *bar;

@end

@implementation NSNotification (EasyAccess)

- (NSString *)foo {
  return [[self userInfo] objectForKey:@"foo"];
}

- (NSNumber *)bar {
  return [[self userInfo] objectForKey:@"bar"];
}

@end
Run Code Online (Sandbox Code Playgroud)

您还可以使用此方法来简化NSNotification创建.例如,您的类别还可能包括:

+ (id)myNotificationWithFoo:(NSString *)foo bar:(NSString *)bar object:(id)object {
  NSDictionary *d = [NSDictionary dictionaryWithObjectsForKeys:foo, @"foo", bar, @"bar", nil];
  return [self notificationWithName:@"MyNotification" object:object userInfo:d];
}
Run Code Online (Sandbox Code Playgroud)

如果由于某些奇怪的原因,您需要属性是可变的,那么您需要使用关联引用来实现:

#import <objc/runtime.h>
static const char FooKey;
static const char BarKey;

...

- (NSString *)foo {
  return (NSString *)objc_getAssociatedObject(self, &FooKey);
}

- (void)setFoo:(NSString *)foo {
  objc_setAssociatedObject(self, &FooKey, foo, OBJC_ASSOCIATION_RETAIN);
}

- (NSNumber *)bar {
  return (NSNumber *)objc_getAssociatedObject(self, &BarKey);
}

- (void)setBar:(NSNumber *)bar {
  objc_setAssociatedObject(self, &BarKey, bar, OBJC_ASSOCIATION_RETAIN);
}

...
Run Code Online (Sandbox Code Playgroud)

  • 经过进一步的反思,这并没有真正解决我的问题.如果我希望NSNotification的所有实例都能获得这些额外的功能,那么添加类别就没问题,但是我希望该选项具有不同的专用通知.也许一个人将携带NSArray类型的有效载荷,而另一个可能携带Some Class作为其有效载荷.我知道我可以使用userInfo作为通知所携带的数据的一种通用转储,但我认为通知专用的更清晰. (2认同)