2012-08-16 55 views
1

我正在写一个类别NSNotificationCenter方法:静态变量和多线程在Objective-C

+(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最初在后台线程上定义,然后在主线程上再次使用,该怎么办?这是否会造成麻烦?有一个更好的方法吗?

回答

2

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

它可能已经实现了dispatch_once之类的东西,这很快。

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

如何在现有的方法,

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

它有几个好处,第一,它是一个基于块的API,这是美妙的处理通知。您的处理代码是正确的。

无论如何,请注意第三个参数。您可以给它一个操作队列,并且通知将在该队列中接收,而不管它从哪个线程发送。

它也是一个更清洁的接口,因为接收者指定处理通知的队列,将发送者与该责任分离。

2

我会建议不要为此创建一个静态变量,每次只得到defaultCenter。否则,您将需要创建适当的锁定机制,这可能会重复可能已在defaultCenter中实施的任何锁定检查,这可能会导致性能/线程安全性更差。如果你还想走这条路线看问题What does your Objective-C singleton look like?

+0

为什么将它存储在局部变量中呢?通话结束后,它会消失,不是?你的意思只是[NSNotificationCenter defaultCenter] postNotifi ...]每一次? – Snowman 2012-08-16 15:23:34

+0

我以为你多次调用它,但我看到你只是在一个if/else语句中调用它,所以不需要将它存储在一个变量中。 – Joe 2012-08-16 15:24:38