2012-08-16 54 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