首先先定義一個protocol
// // Protocols.h // ObserverTest // // Created by Steve on 12/10/5. // Copyright (c) 2012年 Steve. All rights reserved. // #import <Foundation/Foundation.h> @protocol IxxxObserver <NSObject> @required -(void)doSomethingAfterNotify:(NSString*)someStr; @end接著,定義一個observer class,要實作剛剛那個protocol
// // ObserverClass.h // ObserverTest // // Created by Steve on 12/10/5. // Copyright (c) 2012年 Steve. All rights reserved. // #import <Foundation/Foundation.h> #import "Protocols.h" @interface ObserverClass : NSObject <IxxxObserver> @end
// // ObserverClass.m // ObserverTest // // Created by Steve on 12/10/5. // Copyright (c) 2012年 Steve. All rights reserved. // #import "ObserverClass.h" @implementation ObserverClass -(void)doSomethingAfterNotify:(NSString*)someStr { NSLog(@"notified! class %@, with value %@", self, someStr); } @end
然後,定義一個singleton class
拿來add observer, remove observer, 以及notify observer
// // FirstClass.h // ObserverTest // // Created by Steve on 12/10/5. // Copyright (c) 2012年 Steve. All rights reserved. // #import "Protocols.h" #import <Foundation/Foundation.h> @interface FirstClass : NSObject +(FirstClass*)sharedInstance; -(NSString*)regiestObserver:(id<IxxxObserver>)observer; -(void)unregiestObserverWithTicket:(NSString*)ticket; -(void)notifyWithStr:(NSString*)str; @end
// // FirstClass.m // ObserverTest // // Created by Steve on 12/10/5. // Copyright (c) 2012年 Steve. All rights reserved. // #import "FirstClass.h" #import <CommonCrypto/CommonDigest.h> @interface FirstClass () { NSMutableDictionary *mObservers; NSMutableArray *mUnRegTickets; NSMutableDictionary *mNeedToRegObservers; } -(void)doInit; -(NSString*)generateTicket; -(NSString*)timeStrFromTimeObj:(NSDate*)timeObj; -(NSString*)stringToSha1:(NSString*)input; @end @implementation FirstClass static FirstClass *instance = nil; +(FirstClass*)sharedInstance { @synchronized(self) { if (instance == nil){ instance = [[FirstClass alloc] init]; [instance doInit]; } } return instance; } -(void)dealloc { [mObservers release]; [mUnRegTickets release]; [mNeedToRegObservers release]; [super dealloc]; } #pragma mark - public -(NSString*)regiestObserver:(id<IxxxObserver>)observer { NSString *ticket = [self generateTicket]; [mNeedToRegObservers setObject:observer forKey:ticket]; NSLog(@"save reg observer %@ to queue, ticket %@", observer, ticket); return ticket; } -(void)unregiestObserverWithTicket:(NSString*)ticket { [mUnRegTickets addObject:ticket]; NSLog(@"save unreg observer ticket %@ to queue", ticket); } -(void)notifyWithStr:(NSString*)str { @synchronized(self) { // add and remove observers NSLog(@"reg observers from queue"); [mObservers setValuesForKeysWithDictionary:mNeedToRegObservers]; for (NSString *ticket in mUnRegTickets) { NSLog(@"unreg observer %@, ticket %@", [mObservers objectForKey:ticket], ticket); [mObservers removeObjectForKey:ticket]; } [mUnRegTickets removeAllObjects]; [mNeedToRegObservers removeAllObjects]; // update for (id<IxxxObserver> observer in [mObservers allValues]) { NSLog(@"notify observer %@", observer); [observer doSomethingAfterNotify:str]; } } } #pragma mark - private -(void)doInit { mObservers = [[NSMutableDictionary alloc] init]; mUnRegTickets = [[NSMutableArray alloc] init]; mNeedToRegObservers = [[NSMutableDictionary alloc] init]; } -(NSString*)generateTicket { NSString *result = nil; int r = arc4random() % 9999999999; result = [self timeStrFromTimeObj:[NSDate date]]; result = [NSString stringWithFormat:@"%d %@", r, result]; result = [self stringToSha1:result]; return result; } -(NSString*)timeStrFromTimeObj:(NSDate*)timeObj { NSString *result = nil; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; if (!timeObj) { goto EXIT; } [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; result = [dateFormatter stringFromDate:timeObj]; EXIT: [dateFormatter release]; return result; } -(NSString*)stringToSha1:(NSString*)input { const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:input.length]; uint8_t digest[CC_SHA1_DIGEST_LENGTH]; CC_SHA1(data.bytes, data.length, digest); NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { [output appendFormat:@"%02x", digest[i]]; } return output; } @end
最後,使用方法如下…
// // main.m // ObserverTest // // Created by Steve on 12/10/5. // Copyright (c) 2012年 Steve. All rights reserved. // #import <Foundation/Foundation.h> #import "FirstClass.h" #import "ObserverClass.h" int main(int argc, const char * argv[]) { @autoreleasepool { FirstClass *fc = [FirstClass sharedInstance]; ObserverClass *oc = [[ObserverClass alloc] init]; // reg NSString *ticket = [fc regiestObserver:oc]; // notify [fc notifyWithStr:@"XDD"]; // unreg [fc unregiestObserverWithTicket:ticket]; // notify [fc notifyWithStr:@"XDDDD"]; } return 0; }
沒有留言:
張貼留言