• OC与AS3的观察者模式比较以及外部回调


    一.要点

    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并且更灵活的指定观察者.

  • 相关阅读:
    降龙十八掌之三:(见龙在田)优化查询性能
    完整的项目工程目录结构
    降龙十八掌之一:(亢龙有悔)SQL Server Profiler和数据库引擎优化顾问
    ASP.NET状态管理的总结
    LINQ 图解
    获取IP城市
    Eclipse 编译StanfordNLP
    Centos JAVA Eclipse
    关掉PUTTY后,进程仍可以运行。
    centos lnmp 安装笔记
  • 原文地址:https://www.cnblogs.com/lost-1987/p/3208864.html
Copyright © 2020-2023  润新知