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 ...
随机推荐
- django 文档生成器
参考博客:http://www.liujiangblog.com/course/django/160
- MarkDown 使用指南
https://frankbing.gitbooks.io/markdown/content/
- java线程五种状态
java线程五种状态: 创建 -> 就绪 -> 运行 -> 销毁 创建 -> 就绪 -> 运行 -> 等待(缺少资源) -> 销毁 下图:各种状态转换
- HTML常用模板:用DIV实现网站首页、后台管理首页(整理)
1. 说明 网上下载的模板,用DIV实现页面模块之间的分隔(不是用frameset/frame).可以选择有无header/menu/footer,主体如何等等.删除了几个我认为重复的.重新命名而已. ...
- 【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Webserver集群
额.博客名字有点长.. . 前言 最终到这篇文章了,心情是有点激动的. 由于这篇文章会集中曾经博客讲到的全部Nginx功能点.包含主要的负载均衡,还有动静分离技术再加上这篇文章的重点.通过Keepal ...
- Atitti 过程导向 vs 结果导向 attilax的策略
Atitit 世界著名零食 1.1. /////milk hand candy , milk soft candy . fruit soft candy1 1.2. ==========cookie ...
- 【Unity】3.0 第3章 创建和导入3D模型
分类:Unity.C#.VS2015 创建日期:2016-04-02 一.简介 利用Unity内置的基本模型和工具,不需要借助任何其他的三维建模软件,就可以直接创建出各种3D模型,这是这一章我们首先学 ...
- 转:在eclipse中 使用7.0及以上手机进行测试时logcat不打印日志的解决办法
解决办法 替换ADT中的ddmlib.jar文件. 下载ADT对应的zip包,解压出ddmlib.jar文件 放到eclipse\configuration\org.eclipse.osgi\bund ...
- angular学习笔记(三十)-指令(5)-link
这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...
- (原创)用c++11实现简洁的ScopeGuard
ScopeGuard的作用是确保资源面对异常时总能被成功释放,就算没有正常返回.惯用法让我们在构造函数里获取资源,当因为异常或者正常作用域结束,那么在析构函数里释放资源.总是能释放资源.如果没有异常抛 ...