@interface NSProxy <NSObject> {
Class isa;
}
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
Class isa OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}
可以看到固该,它遵守了 NSObject 協(xié)議头谜,并且第一個 Ivar 是一個 isa 指針煞聪,因此它完全是可以拿來當一個 NSObject 或其派生類來使用的雾棺。
NSProxy 的使用也非常簡單膊夹,通常,你只需要實現(xiàn)兩個方法:
- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");
例子轉(zhuǎn)自Cyandev
首先垢村,我們需要準備一個實體類割疾,它可以是任意一個類,甚至是系統(tǒng)類庫所提供的類嘉栓,這里我們用 NSURL 類來開刀宏榕。
@interface MyProxy : NSProxy {
id _object;
}
+ (id)proxyForObject:(id)obj;
@end
@implementation MyProxy
+ (id)proxyForObject:(id)obj {
MyProxy *instance = [MyProxy alloc];
instance->_object = obj;
return instance;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [_object methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
if ([_object respondsToSelector:invocation.selector]) {
NSString *selectorName = NSStringFromSelector(invocation.selector);
NSLog(@"Before calling \"%@\".", selectorName);
[invocation invokeWithTarget:_object];
NSLog(@"After calling \"%@\".", selectorName);
}
}
@end
作者:Cyandev
鏈接:http://www.reibang.com/p/a7187e014c03
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)侵佃,非商業(yè)轉(zhuǎn)載請注明出處麻昼。
這是我們的 Proxy 簡單實現(xiàn),我們需要持有一個被代理對象的引用馋辈,然后將消息轉(zhuǎn)發(fā)到這個對象上抚芦,在轉(zhuǎn)發(fā)之前和以后我們就可以做自己想做的事情了。
methodSignatureForSelector: 方法需要獲取一個方法簽名迈螟,用來生成 NSInvocation叉抡,我們直接將這個調(diào)用轉(zhuǎn)發(fā)到被代理對象中。緊接著答毫,forwardInvocation: 會被調(diào)用褥民,將 NSInvocation 用被代理對象調(diào)用。我們就可以在這個方法里做一些手腳洗搂,比如埋點計數(shù)等消返。在這個例子中,我只是簡單地將對象所調(diào)用的方法的 selector 打印出來耘拇。
然后我們看看用于測試的主函數(shù):
int main(int argc, char *argv[]) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
NSURL *url = [MyProxy proxyForObject:[NSURL URLWithString:@"https://www.google.com"]];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(sem);
}];
[task resume];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return 0;
}
作者:Cyandev
鏈接:http://www.reibang.com/p/a7187e014c03
來源:簡書
著作權(quán)歸作者所有撵颊。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處惫叛。
就是簡單構(gòu)造一個 NSURL倡勇,只不過我們先用了 MyProxy 封裝代理后傳給 NSURLSession 去使用,輸出結(jié)果如下:
也就是說嘉涌,系統(tǒng)用 NSURL 的 absoluteURL 屬性來獲取真正的 URL 數(shù)據(jù)妻熊,至此我們就已經(jīng)可以跟蹤已有類的行為了,甚至還可以通過 [NSThread callStackSymbols] 來跟蹤調(diào)用改方法的函數(shù)調(diào)用棧: