- //向CPMParse注册的回调函数。
- - (void) onCPMIsComing: (NSNotification * ) noti {
- NSDictionary * userInfo = noti.userInfo;
- if ([userInfo isKindOfClass: [NSDictionary class]]) {
- CPMCommand * command = [userInfo objectForKey: kCPMessageParserNotificaitonCommandKey]; //
- if ([command isKindOfClass: [CPMCommand class]]) { [self handleCPM: command];
- }
- }
- }
- //真正处理CPMessage的地方。通过NSInvocation将message命令和UIViewController关联起来
- - (void) handleCPM: (CPMCommand * ) message { [self prepareProcessors];
- CPMItem * item = (CPMItem * )[self.processors objectForKey: NSStringFromCPMessageCommand(message)];
- if (nil == item) {
- return;
- } [item getInfoFromCPMessageCommand: message];
- UIViewController * visibleCtrl = [self.assit topViewController];
- Class receiverClass = NSClassFromString(item.className);
- if (item.classMethod != nil) { [self performClassSelector: item.classMethod onTarget: receiverClass withArgs: item.classArgs]; [item clearInfoFromCPMessageCommand];
- } else if (!item.isOpenAsNew && [visibleCtrl isMemberOfClass: receiverClass]) { // if target viewcontroller is top viewcontroller
- if (item.reloadMethod != nil) { [self performSelector: item.reloadMethod onTarget: visibleCtrl withArgs: item.initialArgs];
- } else if (item.optMethod != nil) { [self performSelector: item.optMethod onTarget: visibleCtrl withArgs: item.optArgs];
- } else {
- // no reloadSEL and no optSEL then do nothing
- } [item clearInfoFromCPMessageCommand];
- } else {
- UIViewController * baseCtl = [item.processor perpareOpeningWithHelpFrom: self.assit];
- //必须要dispatch_async,否则不会回调viewWillDisappear和viewDidDisappear
- dispatch_async(dispatch_get_main_queue(), ^{
- // if target viewcontroller is top viewcontroller
- if (!item.isOpenAsNew && [baseCtl isMemberOfClass: receiverClass]) {
- if (item.reloadMethod != nil) { [self performSelector: item.reloadMethod onTarget: baseCtl withArgs: item.initialArgs];
- } else if (item.optMethod != nil) { [self performSelector: item.optMethod onTarget: baseCtl withArgs: item.optArgs];
- } else {
- // no reloadSEL and no optSEL then do nothing
- }
- } else {
- id receiverSuper = [receiverClass alloc];
- id receiver = [self performSelector: item.initialMethod onTarget: receiverSuper withArgs: item.initialArgs];
- if (nil == receiver || ![receiver isKindOfClass: [UIViewController class]]) { [receiverSuper release];
- } else { [item.processor doOpen: receiver on: baseCtl]; [receiver release];
- }
- } [item clearInfoFromCPMessageCommand];
- });
- }
- }
- /*
- NSInvocation 施展才华的地方,selector和args 调用方法。
- */
- - (id) performSelector: (SEL) aSelector onTarget: (id) target withArgs: (NSArray * ) args {
- id ret = nil;
- if (aSelector == nil || target == nil || ![target respondsToSelector: aSelector]) {
- return ret;
- }
- NSMethodSignature * signature = [target methodSignatureForSelector: aSelector];
- if (args.count + 2 != signature.numberOfArguments) {
- return ret;
- }
- NSInvocation * invocation = [NSInvocation invocationWithMethodSignature: signature]; [invocation setSelector: aSelector]; [invocation setTarget: target];
- for (int i = 2, j = 0; j < args.count; i++, j++) {
- id arg = [args objectAtIndex: j]; [invocation setArgument: &arg atIndex: i];
- } [invocation invoke];
- NSUInteger length = [[invocation methodSignature] methodReturnLength];
- // void *buffer = (void *)malloc(length);
- if (length > 0) { [invocation getReturnValue: &ret];
- }
- return ret;
- } - (id) performClassSelector: (SEL) aSelector onTarget: (Class) target withArgs: (NSArray * ) args {
- id ret = nil;
- if (aSelector == nil || target == nil) {
- return ret;
- }
- NSMutableString * argsInCTypes = [NSMutableString stringWithString: @"v"];
- for (int i = 0; i < args.count; ++i) { [argsInCTypes appendString: @"@:"];
- }
- NSMethodSignature * signature = [target methodSignatureForSelector: aSelector]; // [NSMethodSignature signatureWithObjCTypes:argsInCTypes.UTF8String];
- if (signature == nil || args.count + 2 != signature.numberOfArguments) {
- return ret;
- }
- NSInvocation * invocation = [NSInvocation invocationWithMethodSignature: signature]; [invocation setSelector: aSelector]; [invocation setTarget: target];
- for (int i = 2, j = 0; j < args.count; i++, j++) {
- id arg = [args objectAtIndex: j]; [invocation setArgument: &arg atIndex: i];
- } [invocation invoke];
- NSUInteger length = [[invocation methodSignature] methodReturnLength];
- // void *buffer = (void *)malloc(length);
- if (length > 0) { [invocation getReturnValue: &ret];
- }
- return ret;
- }
- //将UIViewController 的类名、selector分离出来,存到processor中。
- - (void) prepareProcessors {
- NSMutableDictionary * processors = [NSMutableDictionary new];
- CPMType type = -1;
- CPMItem * item = nil;
- //////////////////////////////////////////////////////////////////////////
- type = CPMessageTypeSinglehtml5;
- item = [CPMItem CPMessageItemWithProcessor: [CPMessageProcessors CPMessageProcessorForMessage: type] className: @"webViewController"classMethod: nil initMethod: @selector(initWithsURL: title: ) reloadMethod: @selector(loadWithsURL: title: ) optMethod: nil];
- if (IS_VALID_CPMessageTYPE(type) && (nil != item)) { [processors setObject: item forKey: CPMessageKeys[type]];
- item = nil;
- }
- //添加其他item
- self.processors = processors; [processors release];
- }
来源: http://lib.csdn.net/snippet/ios/43449