您的位置:首页 > 移动开发 > IOS开发

[iOS]使用NSProxy实现代理模式

2012-05-09 09:29 615 查看
// MyProxy.h
#import
<Foundation/Foundation.h>

@interface MyProxy :
NSProxy {

NSObject *object;
}

- (id)transformToObject:(NSObject *)anObject;

@end

// MyProxy.m
#import
"MyProxy.h"

@implementation MyProxy

- (void)dealloc
{
[object
release];

object = nil;
[super
dealloc];
}

- (void)fun
{

// Do someting virtual

//
先做一些代理工作,然后创建一个后台线程,在后台线程中再调用真正的[object fun];
}

// Stupid transform implementation just by assigning a passed in object as transformation target. You can write your factory here and use passed in object as id for object that need
ot be created.
- (id)transformToObject:(NSObject *)anObject
{

if(object != anObject) {
[object
release];
}

object = [anObject retain];

return object;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{

if (object !=
nil) {
[invocation
setTarget:object];

[invocation
invoke];
}
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{

NSMethodSignature *result;

if (object !=
nil) {
result = [object
methodSignatureForSelector:sel];
}
else {

// Will throw an exception as default implementation
result = [super
methodSignatureForSelector:sel];
}

return result;
}

@end

// RealSubject.h
#import
<Foundation/Foundation.h>
@implementation RealSubject : NSObject

- (void)fun;

@end

// RealSubject.m
#import
"RealSubject.h"

@implementation RealSubject

- (void)fun
{

//
这个方法需要代理进行惰性调用

// Do something real
}

- (void)otherFun
{

//
这个方法不需要代理做任何处理,可直接被调用

// Do something real
}

@end

// main.m
int main(int argc,
char *argv[])
{

NSAutoreleasePool * pool = [[NSAutoreleasePool
alloc]
init];

MyProxy *myProxy = [MyProxy
alloc];

RealSubject *realSub = [[RealSubject
alloc] init];
[myProxy
transformToObject:realSub];
[myProxy
fun];
// 直接调用myProxy的fun,执行代理工作
[myProxy
otherFun];
// 依次调用myProxy的methodSignatureForSelector和forwardInvocation转发给realSub,realSub调用otherFun

[realSubject
release];
[myProxy
release];

[pool
release];

return 0;
}

注意,调用MyProxy中未定义的方法otherFun会出现'MyProxy' may not respond to 'fun'的警告,可通过使用私有范畴或通过performSelector:withObject:来避免,如果有更好的方法,请告知。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: