Objective-C中的静态变量和多个线程

时间:2012-08-16 15:08:21

标签: iphone objective-c ios multithreading

我正在使用方法为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最初在后台线程上定义然后在主线程上再次使用,那会怎么样?有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我建议不要为此创建静态变量,每次只获取defaultCenter。否则,您将需要创建正确的锁定机制,该机制可能会复制defaultCenter中可能已实现的任何锁定检查,这可能会导致性能/线程安全性降低。如果您仍想继续这条路线,请查看问题What does your Objective-C singleton look like?

答案 1 :(得分:2)

我同意Joe对静态的看法。另外,如果您能够在调用defaultCenter和使用缓存值之间测量应用程序的差异,我会非常惊讶。

它可能已经实现了像dispatch_once这样的东西,它非常快。

此外,我是否可以建议使用已存在的内容以确保您在正确的帖子上收到通知?

现有方法怎么样,

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

它有几个好处,首先它是一个基于块的API,非常适合处理通知。您的处理代码正确的位置。

无论如何,请注意第三个参数。您可以为其指定一个操作队列,并且无论发送的是哪个线程,都会在该队列上收到通知。

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