1

我正在NSNotificationCenter使用方法编写一个类别:

+(void)postNotificationName:(NSString*)name onMainThread:(BOOL)mainThread withObject:(id)object;

我这样做是为了确保我明确发送通知的线程,因为这给我带来了很多隐藏的问题。[NSNotificationCenter defaultCenter]因此,为了避免每次通过调用每次发布通知时都进行额外的查找,我认为我必须只创建一个静态变量:

static NSNotificationCenter *defaultCenter;
+(void)postNotificationName:(NSString*)name onMainThread:(BOOL)mainThread withObject:(id)object
{
    if(!defaultCenter)
        defaultCenter = [NSNotificationCenter defaultCenter];
    if(mainThread) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [defaultCenter postNotificationName:name object:object];
        });
    } else {
        [defaultCenter postNotificationName:name object:object];
    }
}

我做的安全吗?如果defaultCenter最初在后台线程上定义然后在主线程上再次使用怎么办 - 这是自找麻烦吗?有一个更好的方法吗?

4

2 回答 2

2

我建议不要为此创建静态变量,而defaultCenter每次都获取它。否则,您将需要创建适当的锁定机制,这可能会重复可能已经实现的任何锁定检查,defaultCenter这可能会导致性能/线程安全性变差。如果你还想走这条路,看看你的 Objective-C 单例是什么样子的问题?

于 2012-08-16T15:21:13.607 回答
2

关于静态,我同意乔的观点。此外,如果您甚至能够测量应用程序中调用 defaultCenter 和使用缓存值之间的差异,我会感到非常惊讶。

它可能已经用 dispatch_once 之类的东西实现了,速度非常快。

此外,我是否可以建议使用已经存在的东西来确保您在正确的线程上接收通知?

How about an existing method,

- (id)addObserverForName:(NSString *)name
                  object:(id)obj
                   queue:(NSOperationQueue *)queue
              usingBlock:(void (^)(NSNotification *))block

It has several benefits, first that it is a block-based API, which is wonderful for handling notifications. Your handling code is right where it should be.

Anyway, notice the third parameter. You can give it an operation queue, and the notification will be received on that queue, irregardless of which thread it was sent from.

It is also a cleaner interface, because the receiver is specifying on which queue the notification is handled, decoupling the sender from that responsibility.

于 2012-08-16T23:48:08.663 回答