The system has not already had the notification center Nsnotificationcenter? Why do you have to implement one yourself? Let's consider the following example (most of which I copied the instructions and the original code I wrote on GitHub ):
Among the modules in iOS we use the most nsnotificationcenter. For example, now we have a module that needs to throw a notification and notify the other modules that the username has changed, so let's see how the code is written roughly.
send notice to party nsstring*ConstKusernamechangednotification =@"usernamechangednotification"; NSString*ConstKuseroldnamekey =@"Useroldnamekey"; NSString*ConstKusernewnamekey =@"Usernewnamekey"; Nsnotificationcenter*notificationcenter =[Nsnotificationcenter Defaultcenter]; [Notificationcenter postnotificationname:usernamechangednotificationObject: Nil Userinfo:@{kuseroldnamekey:@"oldname", Usernewnamekey:"NewName"}]; the party receiving the notification can be [[nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (usernamechanged:) Name: KusernamechangednotificationObject: nil]; can also be [[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector ( Usernamechangednotification:) name:kusernamechangednotificationObject: nil];
There are some drawbacks you can see from the examples:
1. For receiving notification of the same event, different people may use different method names and cannot be unified.
2. For multi-parameter support is inconvenient.
For the above two points, write this xmcnotificationcenter, corresponding to the above situation will become the following
<nsobject>-( void ) Usernamechangedwitholdname: (NSString *) oldname newName: (nsstring *) newname;@ Endpostnotification (Userobserver, @selector (usernamechangedwitholdname:newname:), Usernamechangedwitholdname: @ " oldname , Newname:@" newname remove the notification removeobserver (self) when it is released;
Xmcnotificationcenter inside the method is not much, use simple, first define the protocol such as Userobserver, and add inside need to implement method, method for required or optional can
Next is the notifier, as long as the Postnotification macro is used, the parameters are the protocol, the SEL of the method, the method call (there will also be a hint for xcode).
Finally, the Observer, using Addobserverwithprotocol to add their own need to observe the Protocol, and implement Protocol-related methods, if the method is optional, not implemented will not receive notification. Use Removeobserver to remove notifications when they are being released.
Xmcnotificationcenter cannot completely replace Nsnotificationcenter. Because the system is a lot of behavior by nsnotificationcenter notice out. However, if the notification is issued by us, you can use Xmcnotificationcenter. The implementation of the principle is also very simple, using the macro expansion of the characteristics, with a macro to send notifications like calling functions as convenient. The code below, the code is not much: (You can also go to my GitHub xmcnotificationcenter See)
////XMCNotificationCenter.h//Xmcnotificationcenter////Created by Xianmingchen on 16/7/5.//copyright©2016 year Xianmingchen. All rights reserved.//#import<Foundation/Foundation.h>//Add or remove a listener#defineADDOBSERVERWITHPROTOCOL (Observer, Observerprotocol) [[Xmcnotificationcenter Defaultcenter] Addobserver:observer Withprotocolkey: @protocol (Observerprotocol)]#defineREMOVEOBSERVERWITHPROTOCOL (Observer, Observerprotocol) [[Xmcnotificationcenter Defaultcenter] RemoveObserver:o Bserver Withprotocolkey: @protocol (Observerprotocol)]#defineREMOVEOBSERVER (Observer) [[Xmcnotificationcenter Defaultcenter] removeobserver:observer];//Throw Notice#definePostnotification (Observerprotocol, selector, func) \{Nsarray*__observers__ =[[Xmcnotificationcenter Defaultcenter] Observerswithprotocolkey: @protocol (Observerprotocol)]; for(ID Observerinch__observers__) { if([observer Respondstoselector:selector]) {[observer Func]; }}}typedef Protocol*Observerprotocolkey, @interface xmcnotificationcenter:nsobject+ (Xmcnotificationcenter *) Defaultcenter;- (void) Addobserver: (ID) Observer Withprotocolkey: (Observerprotocolkey) key;- (void) Removeobserver: (ID) Observer Withprotocolkey: (Observerprotocolkey) key;- (void) Removeobserver: (ID) observer;-(Nsarray *) Observerswithprotocolkey: (Observerprotocolkey) key; @end
///xmcnotificationcenter.mm//Xmcnotificationcenter////Created by Xianmingchen on 16/7/5.//copyright©2016 year Xianmingchen. All rights reserved.//#import"XMCNotificationCenter.h"Staticcfrange Fullrangewitharray (cfarrayref array);Static voidObserverscallbackfunc (Const void*_key,Const void*_value,void*context);structobservercontext {__weak xmcnotificationcenter*Center; __UNSAFE_UNRETAINED ID observer;}; @interface Xmcnotificationcenter () {cfmutabledictionaryref observersdictionary; dispatch_semaphore_t Semaphore;} @end @implementation Xmcnotificationcenter+ (Xmcnotificationcenter *) defaultcenter{StaticXmcnotificationcenter *center =Nil; Staticdispatch_once_t Oncetoken; Dispatch_once (&oncetoken, ^{Center=[[Xmcnotificationcenter alloc] init]; }); returnCenter;}-(ID) init{ self=[Super Init]; if(self) {cfdictionaryvaluecallbacks kcallback; Kcallback.version=0; Observersdictionary= Cfdictionarycreatemutable (NULL,0, &kcftypedictionarykeycallbacks, &kcftypedictionaryvaluecallbacks); Semaphore= Dispatch_semaphore_create (1); } returnSelf ;}#pragmaMark-add & Remove-(void) Addobserver: (ID) Observer Withprotocolkey: (Observerprotocolkey) key{dispatch_semaphore_wait (semaphore, Dispatch_time_forever); if(![Observer Conformstoprotocol:key]) {#ifdef DEBUG Nsparameterassert (@"Observer not Conformstoprotocol"); #endifNSLog (@"client doesnot conforms to protocol:%@", Nsstringfromprotocol (key)); } cfstringref Cfstringkey=(__bridge cfstringref) Nsstringfromprotocol (key); Cfmutablearrayref Observersarray=(cfmutablearrayref) cfdictionarygetvalue (observersdictionary, Cfstringkey); if(Observersarray = =NULL) {Observersarray= Cfarraycreatemutable (NULL,0, NULL); Cfdictionaryaddvalue (Observersdictionary, Cfstringkey, (Const void*) Observersarray); } Cfrange Range=Fullrangewitharray (Observersarray); BOOL Iscontains= Cfarraycontainsvalue (Observersarray, range, (__bridgeConst void*) (Observer)); if(!iscontains) {Cfarrayappendvalue (Observersarray, (__bridgeConst void*) observer); } dispatch_semaphore_signal (semaphore);}- (void) Removeobserver: (ID) Observer Withprotocolkey: (Observerprotocolkey) key{cfstringref Cfstringkey=(__bridge cfstringref) Nsstringfromprotocol (key); [Self p_removeobserver:observer withkey:cfstringkey];}- (void) P_removeobserver: (ID) Observer Withkey: (CFSTRINGREF) key{dispatch_semaphore_wait (semaphore, dispatch_time_ FOREVER); Cfmutablearrayref Observersarray=(cfmutablearrayref) cfdictionarygetvalue (observersdictionary, key); Cfrange Range=Fullrangewitharray (Observersarray); Cfindex Index= Cfarraygetfirstindexofvalue (Observersarray, range, (__bridgeConst void*) observer); if(Index! =-1) {Cfarrayremovevalueatindex (Observersarray, index); } dispatch_semaphore_signal (semaphore);}- (void) Removeobserver: (ID) observer{dispatch_semaphore_wait (semaphore, dispatch_time_forever); Observercontext context; Context.center=Self ; Context.observer=Observer; Cfdictionaryapplyfunction (Observersdictionary,&observerscallbackfunc, &context); Dispatch_semaphore_signal (semaphore);}#pragmamark-get-(Nsarray *) Observerswithprotocolkey: (observerprotocolkey) key{cfstringref cfstringkey=(__bridge cfstringref) Nsstringfromprotocol (key); Cfarrayref Cfarray=(cfarrayref) cfdictionarygetvalue (observersdictionary, Cfstringkey); Nsarray*array = (__bridge Nsarray *) Cfarray; returnArray;} @end#pragmaMark-otherStaticcfrange Fullrangewitharray (cfarrayref array) {Cfrange range; if(Array = =NULL) { returnrange; } cfindex Length= Cfarraygetcount (Array)-1; if(Length <0) {length=0; } range.location=0; Range.length=length; returnrange;}Static voidObserverscallbackfunc (Const void*_key,Const void*_value,void*context) { if(!context | |!_value | |!_key) { return; } xmcnotificationcenter*center = ((Observercontext *) context)Center; ID Observer= ((Observercontext *) context)Observer; [Center P_removeobserver:observer Withkey: (cfstringref) _key];}
Hope to be of help to everyone.
IOS Nsnotificationcenter (Implement a notification hub yourself Xmcnotificationcenter)