一.要点

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

OC与AS3的观察者模式比较以及外部回调的更多相关文章

  1. as3.0 [Embed]标签嵌入外部资源

    1.[Embed]嵌入资源 ActionScript代码的顺序非常重要.你必须在声明变量前添加[Embed]元数据标签,而且这个变量的类型会是Class; package { import flash ...

  2. 观察者模式在One Order回调函数中的应用

    例如需求是搞清楚function module CRM_PRODUCT_I_A_CHANGE_ORGM_EC在什么样的场景下会被调用.当然最费时间的做法是设一个断点,然后跑对应的场景,观察断点何时被触 ...

  3. 转载:Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式

    Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式 出自:http://www.cnblogs.com/top5/archive/2012/08/04/2623464.html 关 ...

  4. 嵌入式&iOS:回调函数(C)与block(OC)回调对比

    学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...

  5. Go语言实现-观察者模式

    前前言 这个类经过我的正式投入使用啊,发现不对劲,这样做可能会导致线程死锁 比如你dispatch一个event,然后在这个回调里把那个事件的侦听给remove掉了,那么就会导致线程死锁(这个问题找了 ...

  6. iOS下JS与OC互相调用(四)--JavaScriptCore

    前面讲完拦截URL的方式实现JS与OC互相调用,终于到JavaScriptCore了.它是从iOS7开始加入的,用 Objective-C 把 WebKit 的 JavaScript 引擎封装了一下, ...

  7. C++中调用OC代码

    前言 最近项目中为了方便维护,底层统一使用C++编写.由于是项目是做屏幕共享sdk,所以只能底层的压缩.编解码使用C++,屏幕捕获部分Mac和win就自己实现了.那么问题就来了,因为是面向接口编程,所 ...

  8. OC和JS交互的三种方法

    看简书上说一共有六种OC和JS交互的方法,但是前三种原理都一致,都是通过检测.拦截Url地址实现互相调用的.剩下的react native等第三方框架原理不一样,也没有去研究,下边记录我使用的三种方法 ...

  9. OC 与 js 界面JSBridge交互

    // 1.新建WebView self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; [self.view addSubv ...

随机推荐

  1. logstash 中multiline插件的用法

    input { stdin { codec =>multiline { charset=>... #可选 字符编码 max_bytes=>... #可选 bytes类型 设置最大的字 ...

  2. Atitit 架构的原则attilax总结

    Atitit 架构的原则attilax总结 1.1. Rule of three称为"三次原则",指的是当某个功能第三次出现时,才进行"抽象化".是DRY原则和 ...

  3. scala future

    https://docs.scala-lang.org/overviews/core/futures.html https://docs.scala-lang.org/overviews/index. ...

  4. 一文读懂Redis持久化

    Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集合.以及散列等,并且还支持多种排序功能. 什么叫持久 ...

  5. C++11 delete和default

    Defaulted 函数 C++ 的类有四个特殊成员函数,它们分别是:默认构造函数.析构函数.拷贝构造函数以及拷贝赋值运算符.这些类的特殊成员函数负责创建.初始化.销毁,或者拷贝类的对象. 如果程序员 ...

  6. angular.js测试框架protracotr安装所需的node版本

    protractor内代码的语法是基于ES6的,比如:里面用到了展开运算符“...”,node.js 6.0以下是不支持该语法特性. 所以,安装protractor是不会报错,但运行webdriver ...

  7. Python模块学习——tempfile

    主要有以下几个函数: tempfile.TemporaryFile 如何你的应用程序需要一个临时文件来存储数据,但不需要同其他程序共享,那么用TemporaryFile函数创建临时文件是最好的选择.其 ...

  8. 使用BC库解密出现no such provider错误

    使用BC库解密出现no such provider错误 错误提示如下: Exception in thread "main" java.security.NoSuchProvide ...

  9. 泛微OA e-cology8 数据库链接

    数据库恢复 数据库恢复的恢复请按照如下步骤进行: Ø 重新安装对应版本的数据库服务软件 Ø 通过数据库软件本身的还原工具还原备份数据库文件 Sqlserver可以通过企业管理器直接还原备份文件或者附加 ...

  10. Pythonic版冒泡排序和快速排序(附:直接插入排序)

    [本文出自天外归云的博客园] 冒泡排序:就是每次排序选最大元素到数组a的最后,排 len(a)-1 次.也就是两个for循环: 1. 外层是待排数组长度的循环,从待排数组长度(初始待排数组长度等于数组 ...