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并且更灵活的指定观察者.
OC与AS3的观察者模式比较以及外部回调的更多相关文章
- as3.0 [Embed]标签嵌入外部资源
1.[Embed]嵌入资源 ActionScript代码的顺序非常重要.你必须在声明变量前添加[Embed]元数据标签,而且这个变量的类型会是Class; package { import flash ...
- 观察者模式在One Order回调函数中的应用
例如需求是搞清楚function module CRM_PRODUCT_I_A_CHANGE_ORGM_EC在什么样的场景下会被调用.当然最费时间的做法是设一个断点,然后跑对应的场景,观察断点何时被触 ...
- 转载:Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式
Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式 出自:http://www.cnblogs.com/top5/archive/2012/08/04/2623464.html 关 ...
- 嵌入式&iOS:回调函数(C)与block(OC)回调对比
学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...
- Go语言实现-观察者模式
前前言 这个类经过我的正式投入使用啊,发现不对劲,这样做可能会导致线程死锁 比如你dispatch一个event,然后在这个回调里把那个事件的侦听给remove掉了,那么就会导致线程死锁(这个问题找了 ...
- iOS下JS与OC互相调用(四)--JavaScriptCore
前面讲完拦截URL的方式实现JS与OC互相调用,终于到JavaScriptCore了.它是从iOS7开始加入的,用 Objective-C 把 WebKit 的 JavaScript 引擎封装了一下, ...
- C++中调用OC代码
前言 最近项目中为了方便维护,底层统一使用C++编写.由于是项目是做屏幕共享sdk,所以只能底层的压缩.编解码使用C++,屏幕捕获部分Mac和win就自己实现了.那么问题就来了,因为是面向接口编程,所 ...
- OC和JS交互的三种方法
看简书上说一共有六种OC和JS交互的方法,但是前三种原理都一致,都是通过检测.拦截Url地址实现互相调用的.剩下的react native等第三方框架原理不一样,也没有去研究,下边记录我使用的三种方法 ...
- OC 与 js 界面JSBridge交互
// 1.新建WebView self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; [self.view addSubv ...
随机推荐
- lnmp 一键安装
系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian/Deepin Server/Aliyun/Amazon/Mint Linux发行版 需要5GB以上硬盘剩 ...
- unity, particle system Emit from Edge
- mybatis 多数据源
<environments default="development"> <environment id="development"> ...
- 《图说VR入门》——DK2入门及其资源汇总
本文章由cartzhang编写,转载请注明出处. 全部权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/53174895 作者:car ...
- 解决failed to get the required adt version from sdk version
在网上看了很多,选择其中的一个解决方法试了下, 还行. AS 2.3之后不能和Eclipse共用一个SDK,给Eclispe重新配置一个SDK路径
- DCOS :私有云的物理基础架构管理引擎
https://cloud.tencent.com/developer/article/1005598 一.引言 云计算经过多年的发展,逐渐从概念到渐为人认知.到接受.到现在全行业拥抱上云,云的客户也 ...
- nginx 并发数问题思考:worker_connections,worker_processes与 max clients
我相信,很多人都跟我一样,看书都不会太细致也不太认真思考,感觉书中讲的东西都应该是对的,最近读书时我发现以前认为理所当然的东西事实上压根都没有弄明白,最终的结果是,书是别人的,书中的知识也是别人的. ...
- 每天一个linux命令(6):dos2unix unix2dos
dos2unix是将Windows格式文件转换为Unix.Linux格式的实用命令.Windows格式文件的换行符为\r\n ,而Unix&Linux文件的换行符为\n. dos2unix命令 ...
- javascript基础拾遗(九)
1.class关键字 ES6引入了新的class关键字编写对象 function Language(name){ this.name = name this.score = 8.0 } Languag ...
- asp.net上传大文件-请求筛选模块被配置为拒绝超过请求内容长度的请求
HTTP错误404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求,原因是Web服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值(IIS 7 默认文件上传大 ...