NSNotificationCenter
とgcd
&はdispatch_get_main_queue()
非常に異なる目的を果たします。「vs」が本当に当てはまるとは思いません。
NSNotificationCenter
アプリケーションの異なる部分を分離する方法を提供します。たとえばkReachabilityChangedNotification
、Apple の Reachability サンプル コードは、システム ネットワークの状態が変化したときに通知センターに投稿されます。次に、通知センターにセレクター/呼び出しを呼び出すように依頼して、そのようなイベントに応答できるようにすることができます (空襲のサイレンを考えてください)。
gcd
一方、指定したキューで実行する作業をすばやく割り当てる方法を提供します。マルチスレッドとマルチコア CPU を利用するために、コードを分析して個別に処理できるポイントをシステムに伝えることができます。
通常 (ほとんどの場合)、通知は投稿されたスレッドで確認されます。APIの1つの部分の注目すべき例外を除いて...
これらの概念が交差する 1 つの API は、次NSNotificationCenter
のとおりです。
addObserverForName:object:queue:usingBlock:
これは基本的に、特定の通知が特定のスレッドで監視されるようにするための便利な方法です。" usingBlock
" パラメータは、舞台裏でgcd
.
以下はその使用例です。私のコードのどこかにNSTimer
毎秒このメソッドの呼び出しがあるとします:
-(void)timerTimedOut:(NSTimer *)timer{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// Ha! Gotcha this is on a background thread.
[[NSNotificationCenter defaultCenter] postNotificationName:backgroundColorIsGettingBoringNotification object:nil];
});
}
backgroundColorIsGettingBoringNotification
ビューコントローラーのビューの背景色を変更するためのシグナルとしてを使用したいと思います。しかし、それはバックグラウンド スレッドに投稿されています。前述の API を使用して、メイン スレッドでのみそれを観察できます。viewDidLoad
次のコードに注意してください。
@implementation NoWayWillMyBackgroundBeBoringViewController {
id _observer;
}
-(void)observeHeyNotification:(NSNotification *)note{
static NSArray *rainbow = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
rainbow = @[[UIColor redColor], [UIColor orangeColor], [UIColor yellowColor], [UIColor greenColor], [UIColor blueColor], [UIColor purpleColor]];
});
NSInteger colorIndex = [rainbow indexOfObject:self.view.backgroundColor];
colorIndex++;
if (colorIndex == rainbow.count) colorIndex = 0;
self.view.backgroundColor = [rainbow objectAtIndex:colorIndex];
}
- (void)viewDidLoad{
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
__weak PNE_ViewController *weakSelf = self;
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:backgroundColorIsGettingBoringNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
[weakSelf observeHeyNotification:note];
}];
}
-(void)viewDidUnload{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:_observer];
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:_observer];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
この API の主な利点は、postNotification...
呼び出し中に監視ブロックが呼び出されることです。標準 API を使用しobserveHeyNotification:
て次のように実装した場合、ディスパッチ ブロックが実行されるまでの時間は保証されません。
-(void)observeHeyNotification:(NSNotification *)note{
dispatch_async(dispatch_get_main_queue(), ^{
// Same stuff here...
});
}
もちろん、この例ではバックグラウンド スレッドに通知を投稿することはできませんが、どのスレッドに通知を投稿するかについて保証のないフレームワークを使用している場合に便利です。