首先先定義一個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;
}
沒有留言:
張貼留言