NSProxy
An abstract superclass defining an API for objects that act as stand-ins for other objects or for objects that don’t exist yet.
也就是說它是一個(gè)抽象超類货邓,為子類對(duì)象定義API
@interface NSProxy <NSObject> {
Class isa;
}
通常青抛,當(dāng)有消息發(fā)送給NSProxy铅檩,需要轉(zhuǎn)發(fā)給實(shí)際對(duì)象潘明,NSproxy遵循NSObject協(xié)議,提供了消息轉(zhuǎn)發(fā)的通用接口挖腰,它只是實(shí)現(xiàn)了一些基礎(chǔ)方法捉捅,但是它并不提供初始化方法闯捎,當(dāng)收到一些它無法響應(yīng)的消息時(shí)撒蟀,它會(huì)直接拋出異常叙谨。
使用NSProxy,需要?jiǎng)?chuàng)建一個(gè)子類保屯,需要做這些事:
提供初始化方法
重寫methodSignatureForSelector:
methodSignatureForSelector需要給消息參數(shù)提供類型手负,并構(gòu)造NSMethodSignature 對(duì)象respondsToSelector:
是否響應(yīng)一個(gè)SEL重寫forwardInvocation:
forwardInvocation應(yīng)該處理整個(gè)調(diào)用流程所需要的任何操作,例如通過網(wǎng)絡(luò)轉(zhuǎn)發(fā)調(diào)用或加載實(shí)際對(duì)象并將調(diào)用傳遞給它
實(shí)際應(yīng)用
使用NSProxy來避免循環(huán)引用
使用WeakProxy來實(shí)現(xiàn)弱引用
創(chuàng)建NSProxy子類
WeakProxy.h
@interface WeakProxy : NSProxy
@property (weak,nonatomic,readonly)id target;
+ (instancetype)proxyWithTarget:(id)target;
- (instancetype)initWithTarget:(id)target;
@end
WeakProxy.m
#import "WeakProxy.h"
@implementation WeakProxy
- (instancetype)initWithTarget:(id)target{
_target = target;
return self;
}
+ (instancetype)proxyWithTarget:(id)target{
return [[self alloc] initWithTarget:target];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
SEL sel = [invocation selector];
if ([self.target respondsToSelector:sel]) {
[invocation invokeWithTarget:self.target];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSMethodSignature *s = [self.target methodSignatureForSelector:aSelector];
return s;
}
- (BOOL)respondsToSelector:(SEL)aSelector{
return [self.target respondsToSelector:aSelector];
}
@end
self.timer = [NSTimer timerWithTimeInterval:1
target:[WeakProxy proxyWithTarget:self]
selector:@selector(print:)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
實(shí)現(xiàn)多繼承
創(chuàng)建NSProxy子類TargetProxy
TargetProxy.h
@interface TargetProxy : NSProxy
- (id)initWithTarget1:(id)t1 target2:(id)t2;
@end
創(chuàng)建Study類
@interface Student : NSObject
- (void)study;
@end
TargetProxy.m
@interface TargetProxy ()
@property(nonatomic, strong) id realObject1;
@property(nonatomic, strong) id realObject2;
@end
@implementation TargetProxy
- (id)initWithTarget1:(id)t1 target2:(id)t2 {
self.realObject1 = t1;
self.realObject2 = t2;
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *sig;
sig = [self.realObject1 methodSignatureForSelector:aSelector];
if (sig) return sig;
sig = [self.realObject2 methodSignatureForSelector:aSelector];
return sig;
}
// Invoke the invocation on whichever real object had a signature for it.
- (void)forwardInvocation:(NSInvocation *)invocation {
id target = [self.realObject1 methodSignatureForSelector:[invocation selector]] ? self.realObject1 : self.realObject2;
[invocation invokeWithTarget:target];
}
// Override some of NSProxy's implementations to forward them...
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([self.realObject1 respondsToSelector:aSelector]) return YES;
if ([self.realObject2 respondsToSelector:aSelector]) return YES;
return NO;
}
NSMutableString *string = [[NSMutableString alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
id proxy = [[TargetProxy alloc] initWithTarget1:string target2:array];
[proxy appendString:@"This "];
[proxy appendString:@"is "];
[proxy addObject:string];
[proxy appendString:@"a "];
[proxy appendString:@"test!"];
NSLog(@"count should be 1, it is: %lu", (unsigned long)[proxy count]);
if ([[proxy objectAtIndex:0] isEqualToString:@"This is a test!"]) {
NSLog(@"Appending successful.");
} else {
NSLog(@"Appending failed, got: '%@'", proxy);
}
這樣TargetProxy就同時(shí)繼承了NSMutableString類和NSMutableArray類