NSNotificationCenter
और gcd
& dispatch_get_main_queue()
बहुत अलग उद्देश्यों को पूरा करता है। मैं बात नहीं करता "बनाम" वास्तव में लागू है।
NSNotificationCenter
आपके आवेदन के अलग-अलग हिस्सों को डी-युग्मन करने का एक तरीका प्रदान करता है। उदाहरण के लिए ऐप्पल के रीचैबिलिटी नमूना कोड में kReachabilityChangedNotification
सिस्टम नेटवर्क स्थिति बदलते समय अधिसूचना केंद्र पर पोस्ट किया गया है। और बदले में आप अपने चयनकर्ता/आमंत्रण को कॉल करने के लिए अधिसूचना केंद्र से पूछ सकते हैं ताकि आप इस तरह की घटना का जवाब दे सकें। (सोचें एयर रेड साइरेन)
gcd
दूसरी तरफ काम करने का एक त्वरित तरीका प्रदान करता है आपके द्वारा निर्दिष्ट एक कतार। यह आपको सिस्टम को उन बिंदुओं को बताने देता है जिन पर आपके कोड को विच्छेदित किया जा सकता है और एकाधिक-थ्रेड और बहु-कोर CPUs का लाभ उठाने के लिए अलग से संसाधित किया जा सकता है।
आम तौर पर (लगभग हमेशा) अधिसूचनाओं को उस धागे पर देखा जाता है जिस पर उन्हें पोस्ट किया जाता है। एपीआई के एक टुकड़ा के उल्लेखनीय अपवाद ... के साथ
एपीआई के एक टुकड़ा जहां अवधारणाओं को इन एक दूसरे को काटना 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
उपयोग करने के लिए मेरे विचार नियंत्रक के दृश्य की पृष्ठभूमि का रंग बदलना चाहते हैं। लेकिन यह एक पृष्ठभूमि धागे पर पोस्ट किया गया है। खैर मैं उपर्युक्त एपीआई का उपयोग केवल यह देखने के लिए कर सकता हूं कि केवल मुख्य धागे पर।निम्नलिखित कोड में 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
इस एपीआई के प्राथमिक लाभ होने के लिए है कि अपने को देख ब्लॉक postNotification...
कॉल के दौरान कहा जाएगा लगता है। आप मानक एपीआई का इस्तेमाल किया और observeHeyNotification:
तरह लागू किया, तो निम्न कोई गारंटी नहीं है कि इसमें कितना समय से पहले अपने प्रेषण ब्लॉक मार डाला गया था होगा वहाँ होगा:
-(void)observeHeyNotification:(NSNotification *)note{
dispatch_async(dispatch_get_main_queue(), ^{
// Same stuff here...
});
}
इस उदाहरण में बेशक आप बस एक पर अधिसूचना पोस्ट नहीं कर सके पृष्ठभूमि धागा, लेकिन यह आसान हो सकता है यदि आप एक ढांचे का उपयोग कर रहे हैं जो इस बात की कोई गारंटी नहीं देता है कि यह किस धागे पर अधिसूचनाएं पोस्ट करेगा।
वे वास्तव में परस्पर अनन्य विकल्प नहीं हैं। आप बैकग्राउंड थ्रेड पर काम करने के लिए जीसीडी का उपयोग कर सकते हैं, फिर मुख्य थ्रेड पर वापस स्विच करें और एनएसएनोटिफिकेशन भेजें (जिसे उसी धागे पर प्राप्त किया जाता है)। या मैं सवाल समझ नहीं रहा हूँ? – Kitsune
@ किट्स्यून मुझे एहसास है कि दोनों को खुशी से एक साथ इस्तेमाल किया जा सकता है, अगर कोई ज्ञात मामला है जहां एक या दूसरे का हमेशा प्रयोग होता है/बचा जाता है तो मैं उत्सुक हूं। मैं ऐसे उदाहरण देख रहा हूं जहां जीसीडी लगातार पृष्ठभूमि धागे पर काम भेजने के लिए प्रयोग किया जाता है लेकिन कभी-कभी अधिसूचना मुख्य धागे पर लौटने के लिए उपयोग की जाती है और दूसरी बार, जीसीडी मुख्य धागे पर वापस जाने के लिए प्रयोग किया जाता है। – Endophage
आप जानते हैं कि अधिसूचनाएं उसी धागे पर वितरित की जाती हैं जिन्हें वे पोस्ट किए जाते हैं? तो वे "मुख्य धागे पर लौटने" के लिए इस्तेमाल नहीं किया जा सकता है! – Felix