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 ...
随机推荐
- FFT节省资源的思路
作者:桂. 时间:2017-01-18 23:07:50 链接:http://www.cnblogs.com/xingshansi/articles/6298391.html 前言 FFT是信号处理 ...
- android check box 自定义图片
http://blog.csdn.net/competerh_programing/article/details/7417074
- Mysql 导入CSV数据 语句 导入时出现乱码的解决方案
1. 登陆mysql 2. use testdb 3. 执行导入语句 LOAD DATA LOCAL INFILE 'd://exportedtest2.csv' INTO TABLE usertab ...
- 如何使用好android的可访问性服务(Accessibility Services)
原文:http://android.eoe.cn/topic/android_sdk * 主题* Manifest声明和权限 可访问性服务声明 可访问性服务配置 AccessibilityServic ...
- xcode6 怎样下载ios7模拟器
1. 怎样下载ios7模拟器 点击xcode.选择"Preferences".选择"downloads",就能够看见IOS 7.1,只是下载有点慢. 2. 怎样 ...
- SQL存储过程教程
一直以来,对SQL SERVER的存储过程和触发器都基本没有用到,只是偶尔从网上找几个简单的函数PASTE到我的SQL中用.自己写总是感觉缺点什么,前几天单位的培训讲了一天的SQL SERVER, ...
- Python使用读写excel文件
Python使用openpyxl读写excel文件 这是一个第三方库,可以处理xlsx格式的Excel文件.pip install openpyxl安装.如果使用Aanconda,应该自带了. 读取E ...
- socket.io笔记一
//服务端代码 var server = require('http').createServer(app); var io = require('socket.io')(server,{path:' ...
- C++标准库及其保留字(关键字)——附:C++标准文档
引言 C++到目前共发布了4个国际标准:ISO/IEC 14882:1998.ISO/IEC 14882:2003.ISO/IEC 14882:2011.ISO/IEC 14882:20 ...
- cmd命令操作Oracle数据库
//注意cmd命令执行的密码字符不能过于复杂 不能带有特殊符号 以免执行不通过 譬如有!@#¥%……&*之类的 所以在Oracle数据库设置密码是不要太复杂 /String Database ...