1
2
[错误代码示范]
@interface UIViewController (Track)
- (void)testTrack;
- (void)handleTrack:(id)arg withSelector:(NSString*)sel withDict:(NSDictionary*)eventDict;
@end
@implementation UIViewController (Track)
- (void)testTrack
{
NSLog(@"- (void)testTrack");
}
- (void)handleTrack:(id)arg withSelector:(NSString*)sel withDict:(NSDictionary*)eventDict
{
NSLog(@"- (void)handleTrack");
id<AspectInfo> aspectInfo = arg;
NSLog(@"\n AspectHandlerBlock [%@]\n \n**-**", [[aspectInfo instance] class]);
NSLog(@"\n AspectInfo originalInvocation<%@>, \n<%@>", aspectInfo.originalInvocation, aspectInfo.arguments);
//特殊动态处理,动态获取labelName || eventID
NSString * labelString = eventDict[TrackEvent_Label];
NSString * idString = eventDict[TrackEvent_ID];
if (eventDict[TrackEvent_Action]) {
NSString * actionString = eventDict[TrackEvent_Action];
//!!!!!!!!!!注意在这错误
NSString * tmpString = [self valueForKey:actionString];
NSDictionary * trackDict = @{eventDict[TrackEvent_Value]:tmpString};
//!nil
if (idString && labelString && trackDict) {
NSLog(@"--TalkingData trackEvent--%@,%@,%@", idString, labelString, trackDict);
}
}else if (idString && labelString){
NSLog(@"--TalkingData trackEvent--%@,%@", idString, labelString);
}
}
@end
文章参考:
http://objc-zen-book.books.yourtion.com/Chapter12/01-aspect-oriented-programming.html
http://www.jianshu.com/p/0497afdad36d#
http://tech.glowing.com/cn/method-swizzling-aop/
http://www.jianshu.com/p/69859d580354
http://www.bingjie.me/2015/11/05/OC%E4%B8%ADaspect%E5%88%87%E9%9D%A2%E7%BC%96%E7%A8%8B%E5%BA%94%E7%94%A8.html
对应代码参考:
https://github.com/weng1250/UserStatisticsWithRuntime
https://github.com/okcomp/AspectsDemo
https://github.com/steipete/Aspects
https://github.com/MikeFighting/LogByRunTime
扩展学习
参考源码分析
https://github.com/devedbox/AXWebViewController
aspect_hookSelector
知识扩展:
【1】
+ (void)load{
swizzleMethod([self class], @selector(viewDidAppear:), @selector(swizzled_viewDidAppear:));
}
一般情况下,类别里的方法会重写掉主类里相同命名的方法。如果有两个类别实现了相同命名的方法,只有一个方法会被调用。但 +load: 是个特例,当一个类被读到内存的时候, runtime 会给这个类及它的每一个类别都发送一个 +load: 消息。
【2】Runtime
object_getIvar 获得类的变量(包括“所谓私有变量”)
转自 http://blog.csdn.net/lvdezhou/article/details/49509805
OBJC_EXPORT id object_getIvar(id obj, Ivar ivar)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
#import <objc/runtime.h>
Person * p1 = [[Person alloc] init];
Ivar ivar = class_getInstanceVariable([p1 class], "_sex");
id sex = object_getIvar(p1, ivar);
NSLog(@"%@", sex);//p1.sex=@"girl";结果为girl