उद्देश्य-सी में NSNotificationCenter के माध्यम से संदेश भेजें और प्राप्त करें?


610

मैं NSNotificationCenterउद्देश्य-सी के माध्यम से संदेश भेजने और प्राप्त करने का प्रयास कर रहा हूं । हालाँकि, मैं ऐसा करने के लिए कोई उदाहरण नहीं पा सका हूँ। आप किस माध्यम से संदेश भेजते और प्राप्त करते हैं NSNotificationCenter?


वास्तव में बहुत उपयोगी है, धन्यवाद। एक बात, addObserver विधि में निर्दिष्ट चयनकर्ता के बाद अनुगामी अर्ध बृहदान्त्र नहीं होना चाहिए (कम से कम इसके कारण मेरे संस्करण में इसका अपवाद हुआ)। मैंने ऊपर दिए कोड को संपादित करने की कोशिश की, लेकिन मूल कोड में प्रारूपण के मुद्दों के कारण परिवर्तन स्वीकार नहीं किया गया।
ब्रौनियस

3
यह बहुत अच्छा था: cocoawithlove.com/2008/06/…
अराम

2
यह क्ष बहुत मूल और व्यापक है, थोड़ा सा
गूगलिंग

यह एक संबंधित प्रश्न के समान है: stackoverflow.com/questions/7896646/…
डेविड डगलस

55
मुझे लगता है कि यह एक ऐसा प्रश्न है, जब स्टैक ओवरफ्लो के उपयोगकर्ताओं ने इसकी उपयोगिता पर स्पष्ट रूप से टिप्पणी की है, यह एक रचनात्मक नहीं है
Chet

जवाबों:


1019
@implementation TestClass

- (void) dealloc
{
    // If you don't remove yourself as an observer, the Notification Center
    // will continue to try and send notification objects to the deallocated
    // object.
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

- (id) init
{
    self = [super init];
    if (!self) return nil;

    // Add this instance of TestClass as an observer of the TestNotification.
    // We tell the notification center to inform us of "TestNotification"
    // notifications using the receiveTestNotification: selector. By
    // specifying object:nil, we tell the notification center that we are not
    // interested in who posted the notification. If you provided an actual
    // object rather than nil, the notification center will only notify you
    // when the notification was posted by that particular object.

    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(receiveTestNotification:) 
        name:@"TestNotification"
        object:nil];

    return self;
}

- (void) receiveTestNotification:(NSNotification *) notification
{
    // [notification name] should always be @"TestNotification"
    // unless you use this method for observation of other notifications
    // as well.

    if ([[notification name] isEqualToString:@"TestNotification"])
        NSLog (@"Successfully received the test notification!");
}

@end

... कहीं दूसरी कक्षा में ...

- (void) someMethod
{

    // All instances of TestClass will be notified
    [[NSNotificationCenter defaultCenter] 
        postNotificationName:@"TestNotification" 
        object:self];

}

2
बस यह सोचकर कि [NSNotificationCenter defaultCenter] को कहां रखा गया है। क्या इसे अपने AppDelegate में रखना सबसे अच्छा है?
फुलवियो

14
@ फुल्वियो: यह निर्भर करता है, यदि आप सूचनाएं प्राप्त कर रहे हैं या पोस्ट कर रहे हैं जो संभावित रूप से आपके आवेदन के सभी हिस्सों को प्रभावित करते हैं, तो इसे अपने अपीलीगेट में डाल दें। यदि आप ऐसी सूचनाएं प्राप्त / पोस्ट कर रहे हैं जो केवल एकल वर्ग को प्रभावित करती हैं, तो इसे उस वर्ग में रखें।
ड्रीमलैक्स

1
@dreamlax सत्य, हालांकि यह ध्यान देने योग्य है क्योंकि यह प्रश्न ज्यादातर नए आईओएस देवों द्वारा खोजा जाता है जो अधिसूचना श्रोता को उनकी आवश्यकता से अधिक समय तक जीवित रखते हैं। अब चाप के साथ आप आमतौर पर डीललोक का उपयोग नहीं करते हैं और परिणामस्वरूप कुछ लोग सोच सकते हैं कि उन्हें श्रोता को रिहा नहीं करना है।
Vive

7
यह भी ध्यान देने योग्य हो सकता है कि [super dealloc]एआरसी के तहत डीललोक-विधि में कॉल की अनुमति नहीं है; बाकी सब अच्छा है।
टॉमी

1
यदि अधिसूचना भड़कती है और कोई पर्यवेक्षक नहीं हैं तो क्या होगा? क्या अधिसूचना खो गई है? या क्या इसे "सहेजा गया" कहीं नए प्रेक्षक (बाद में बनाया गया) को भेजने के लिए तैयार है?
सुपरपुकियो

226

ड्रीमलैक्स के उदाहरण पर विस्तार करने के लिए ... यदि आप अधिसूचना के साथ डेटा भेजना चाहते हैं

पोस्टिंग कोड में:

NSDictionary *userInfo = 
[NSDictionary dictionaryWithObject:myObject forKey:@"someKey"];
[[NSNotificationCenter defaultCenter] postNotificationName: 
                       @"TestNotification" object:nil userInfo:userInfo];

कोड देखने में:

- (void) receiveTestNotification:(NSNotification *) notification {

    NSDictionary *userInfo = notification.userInfo;
    MyObject *myObject = [userInfo objectForKey:@"someKey"];
}

TestNotification NSString प्रकार का होना चाहिए। क्या यह एक उदाहरण चर NSNotification है?
रोमनहाउस

1
क्या मैं selfgetTestNotification विधि में पर्यवेक्षक तक पहुँच प्राप्त कर सकता हूँ ?
क्यों

क्यों हां। ReceTestNotification एक इंस्टेंस विधि है, और आपके पास स्वयं के माध्यम से इंस्टेंस तक पहुंच है।
माइकल पीटरसन

बस। मैं रिसीवर विधि से UserInfo प्राप्त करने के लिए एक रास्ता तलाश रहा था।
हसन

ऐसा लगता है कि पर्यवेक्षक विचार सभी मामलों को कवर नहीं करता है। जब ऐप काम नहीं करता था। बंद कर दिया गया था और एक सूचना प्रपत्र अधिसूचना केंद्र पर टैप हो गया। प्रेक्षक विधि कहा जाता है।
हसन

49

इसने मेरी मदद की:

// Add an observer that will respond to loginComplete
[[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(showMainMenu:) 
                                                 name:@"loginComplete" object:nil];


// Post a notification to loginComplete
[[NSNotificationCenter defaultCenter] postNotificationName:@"loginComplete" object:nil];


// the function specified in the same class where we defined the addObserver
- (void)showMainMenu:(NSNotification *)note {
    NSLog(@"Received Notification - Someone seems to have logged in"); 
}

स्रोत: http://www.smipple.net/snippet/Sounden/Simple%20NSNotificationCenter%20xample


यह मेरे लिए काम किया! धन्यवाद
Rakshitha Muranga रॉड्रिगो

48

ब्लॉक का उपयोग करने की संभावना भी है:

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[[NSNotificationCenter defaultCenter] 
     addObserverForName:@"notificationName" 
     object:nil
     queue:mainQueue
     usingBlock:^(NSNotification *notification)
     {
          NSLog(@"Notification received!");
          NSDictionary *userInfo = notification.userInfo;

          // ...
     }];

Apple का प्रलेखन


1
यह मेरे उत्तर के लिए एक अच्छा अद्यतन है जो अब काफी पुराना है। परिचय या एआरसी और ब्लॉक के साथ, अधिसूचना केंद्रों से निपटना बहुत आसान है।
ड्रीमलैक्स

5
मैंने भी ऐसा सोचा था, लेकिन यह पता चला है कि यह सच होना बहुत अच्छा है। इस स्थिति में आपको उस पर्यवेक्षक को बनाए रखना होगा जो AddObserver देता है और बाद में इसे हटा देता है, जो इसे एक नई विधि बनाने के रूप में जटिल बनाता है, यदि ऐसा नहीं है। अधिक जानकारी: toastmo.com/blog/2012/12/04/…
एंड्रयू

42

यदि आप अपना दृष्टिकोण अपडेट करने के लिए NSNotificationCenter का उपयोग कर रहे हैं, तो कॉल करके इसे मुख्य धागे से भेजना न भूलें dispatch_async:

dispatch_async(dispatch_get_main_queue(),^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"my_notification" object:nil];
});

1
क्या यह अधिसूचना पोस्ट है जिसे मुख्य धागे से प्राप्त करने की आवश्यकता है, या जब आप वास्तव में दृश्य को अपडेट करते हैं, अर्थात, अधिसूचना प्राप्त करने की विधि के अंदर आप मुख्य धागे को भेजते हैं?
Crashalot

1
जिस थ्रेड से आप सूचना भेजते हैं, वह फ़ंक्शन चलाने वाला थ्रेड है, और इस प्रकार UI को बदलने का प्रयास किया जाता है। आप फ़ंक्शंस के अंदर मुख्य थ्रेड को भी भेज सकते हैं, जैसे आपने कहा: D। एक ही परिणाम होना चाहिए, यह बेहतर है
perheps

1
@ ईरन, बहुत बहुत धन्यवाद भाई, यह मैंने डिस्पैच_संकल के अंदर लिखने के बाद ही काम किया
अरशद शैक

2

Newbies के लिए चयनित उत्तर का SWIFT 5.1

class TestClass {
    deinit {
        // If you don't remove yourself as an observer, the Notification Center
        // will continue to try and send notification objects to the deallocated
        // object.
        NotificationCenter.default.removeObserver(self)
    }

    init() {
        super.init()

        // Add this instance of TestClass as an observer of the TestNotification.
        // We tell the notification center to inform us of "TestNotification"
        // notifications using the receiveTestNotification: selector. By
        // specifying object:nil, we tell the notification center that we are not
        // interested in who posted the notification. If you provided an actual
        // object rather than nil, the notification center will only notify you
        // when the notification was posted by that particular object.

        NotificationCenter.default.addObserver(self, selector: #selector(receiveTest(_:)), name: NSNotification.Name("TestNotification"), object: nil)
    }

    @objc func receiveTest(_ notification: Notification?) {
        // [notification name] should always be @"TestNotification"
        // unless you use this method for observation of other notifications
        // as well.

        if notification?.name.isEqual(toString: "TestNotification") != nil {
            print("Successfully received the test notification!")
        }
    }
}

... कहीं दूसरी कक्षा में ...

 func someMethod(){
        // All instances of TestClass will be notified
        NotificationCenter.default.post(name: "TestNotification", object: self)
 }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.