一.要点
1.AS3的观察者模式,主要是体现在在哪个组件上监听,那么就在这个组件上分发事件,并且可以直接传递Function.
2.OC的观察者模式,主要是需要你指定观察的对象,和观察的对象方法selector,selector只是一个方法的指示器,OC并不能直接传递这个方法,所以你必须指定观察者的对象.
二.实例
1.AS3
amf.as
package com.ylsoft.core { import com.ylsoft.event.AppEvent; import mx.controls.Alert; import mx.core.FlexGlobals; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.rpc.remoting.RemoteObject; public class Amf { private var _remoteObject : UIRemoteObject; private static var _self : Amf; private var _result:Object; private var _callback : Function ; private var _faultMsg:String; private var _use_waiting_image:*; public function Amf() { //singleton this._remoteObject = new UIRemoteObject(); } /** * 注册result返回的回调函数 * */ public function registerCallBack(callback:Function):void{ //再application上注册这个函数 this._remoteObject.addEventListener(AppEvent.AMF_GLOABAL_COMPLETE,callback); this._callback = callback; } public function setFaultMessage(msg:String):void{ this._faultMsg = msg; } public function startService(service:String,method:String,...arguments):Amf{ //清空结果 this._result = null; //开始调用 this._remoteObject.showBusyCursor = false; this._remoteObject.destination = 'amfphp';//必须指定 并不一定需要service-config.xml 因为endpoint会指定destination this._remoteObject.source = service; this._remoteObject.endpoint = AppConfig.AMFURL; this._remoteObject.addEventListener(ResultEvent.RESULT,returnData); this._remoteObject.addEventListener(FaultEvent.FAULT,showFault); this._remoteObject.use_waiting_image = this._use_waiting_image == null ? AppConfig.USE_WAITING_IMAGE : this._use_waiting_image as Boolean; if(arguments.length == 0){ this._remoteObject.getOperation(method).send(''); return this; } switch(arguments.length){ case 1:this._remoteObject.getOperation(method).send(arguments[0]);break; case 2:this._remoteObject.getOperation(method).send(arguments[0],arguments[1]);break; case 3:this._remoteObject.getOperation(method).send(arguments[0],arguments[1],arguments[2]);break; } return this; } private function returnData(evt:ResultEvent):void{ this._result = evt.result;//先吧结果赋值在触发完成事件 这样在回调中就不会出现空result的错误了 this._remoteObject.dispatchEvent(new AppEvent(AppEvent.AMF_GLOABAL_COMPLETE)); this.clearEvent(); // Alert.show(evt.result.toString()); } private function showFault(evt:FaultEvent):void{ if(this._faultMsg!=null){ Alert.show(this._faultMsg); }else{ Alert.show(evt.fault.message); } this.clearEvent(); } public function getResult():Object{ return this._result; } private function clearEvent():void{ this._remoteObject.removeEventListener(ResultEvent.RESULT,returnData); this._remoteObject.removeEventListener(FaultEvent.FAULT,showFault); this._remoteObject.removeEventListener(AppEvent.AMF_GLOABAL_COMPLETE,this._callback); FlexGlobals.topLevelApplication.dispatchEvent(new AppEvent(AppEvent.UIREMOTEOBJECT_FINISH)); } public function get use_waiting_image():* { return _use_waiting_image; } public function set use_waiting_image(value:*):void { _use_waiting_image = value; } } }
外部调用
amf = new Amf(); amf.setFaultMessage("通信失败"); amf.registerCallBack(initDataGrid); amf.startService('dailyCopyDataService','lists',new Pagelimit(0,AppConfig.PAGECOUNT),getCondition()); function initDataGrid(e:AppEvent):void{ //code here } 那么当_remoteObject 分发请求完成事件的时候就会调用initDataGrid 这个方法了
2.objective-c
viewController.h
// // ViewController.h // rpc // // Created by 卜 峘 on 13-7-22. // Copyright - (void)connectionDidFinishLoading:(NSURLConnection *)connection;年 卜 峘. All rights reserved. // #import <UIKit/UIKit.h> #import "URLConnectionImpl.h" #import "CJSONDeserializer.h" @interface ViewController : UIViewController { @private URLConnectionImpl *impl; IBOutlet UIButton *rpcbtn; } @property(nonatomic,retain) URLConnectionImpl *impl; @property(nonatomic,retain) IBOutlet UIButton *rpcbtn; -(IBAction)send:(id)sender; -(void)fetchData:(id)sender; @end
viewController.m
// // ViewController.m // rpc // // Created by 卜 峘 on 13-7-22. // Copyright (c) 2013年 卜 峘. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController @synthesize impl; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. impl = [[[URLConnectionImpl alloc]autorelease ]init]; impl.executeData = @selector(fetchData:);//注册接收数据的回调函数 impl.target = self;//设置调用fetchData 的对象 } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)send:sender{ NSString *address = @"http://127.0.0.1/oc/test.php"; NSURL *url = [[[NSURL alloc]autorelease ] initWithString:address]; NSURLRequest *req = [[[NSURLRequest alloc] autorelease]initWithURL:url]; NSURLConnection *conn = [[[NSURLConnection alloc] autorelease] initWithRequest:req delegate:impl]; } -(void)fetchData:(id)sender{ //从通知中心得到数据 NSData *data = [[sender userInfo]objectForKey:@"data"]; NSDictionary *dic = [[CJSONDeserializer deserializer] deserializeAsDictionary:data error:nil]; NSLog(@"%@",[dic objectForKey:@"name"]); } @end
URLConnectionImpl.h
// // URLConnectionImpl.h // rpc // // Created by 卜 峘 on 13-7-22. // Copyright (c) 2013年 卜 峘. All rights reserved. // NSURLConnection 的代理实现类 需在nsurlconnection的delegate参数中传入本类的实例 // 主要功能 实现数据的外部回调 // #import <Foundation/Foundation.h> @interface URLConnectionImpl : NSObject <NSURLConnectionDelegate,NSURLConnectionDataDelegate>{ SEL executeData; //执行回调的对象里的方法 NSObject *target;//执行回调的对象 } @property SEL executeData; @property(nonatomic,retain) NSObject *target; @end
URLConnectionImpl.m
// // URLConnectionImpl.m // rpc // // Created by 卜 峘 on 13-7-22. // Copyright (c) 2013年 卜 峘. All rights reserved. // #import "URLConnectionImpl.h" @implementation URLConnectionImpl @synthesize executeData; @synthesize target; - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"%@",error); } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ [[NSNotificationCenter defaultCenter]addObserver:self.target selector:self.executeData name:@"fetchWebServiceData" object:nil];//注册通知 实际上这里的selector也就是个char*类型 猜测内部应该是 [self.target self.executeData]这样的调用方式 } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [[NSNotificationCenter defaultCenter]postNotificationName:@"fetchWebServiceData" object:self.target userInfo:[NSDictionary dictionaryWithObject:data forKey:@"data"]];//发送通知 } - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ } @end
相比之下OC这种方式更为灵活一些,能够随意分配指定delegate并且更灵活的指定观察者.