Authored by 孙凯

修改 hook 逻辑 review by daiqiang

... ... @@ -88,7 +88,7 @@ void yher_collectionViewDidSelectItemAtIndexPath(id self, SEL _cmd, id collectio
if (!view) {
return;
}
[YH_EventCollector trackAppClickWithView:self UICollectionView:collectionView didSelectItemAtIndexPath:indexPath];
} @catch (NSException *exception) {
YHLog(@"%@ error: %@", self, exception);
... ... @@ -100,38 +100,22 @@ void yher_collectionViewDidSelectItemAtIndexPath(id self, SEL _cmd, id collectio
[self yher_collectionViewSetDelegate:delegate];
@try {
SEL swizzledMethodSEL = @selector(collectionView:didSelectItemAtIndexPath:);
if (![delegate respondsToSelector:swizzledMethodSEL]) {
SEL originMethodSEL = @selector(collectionView:didSelectItemAtIndexPath:);
if (![delegate respondsToSelector:originMethodSEL]) {
return;
}
Class class = [delegate class];
Class delegateClass = [delegate class];
SEL originMethodSEL = NSSelectorFromString(@"yher_collectionViewDidSelectItemAtIndexPath");
if (class_addMethod(class, originMethodSEL, (IMP)yher_collectionViewDidSelectItemAtIndexPath, "v@:@@")) {
Method dis_swizzledMethod = class_getInstanceMethod(class, swizzledMethodSEL);
//若子类实现了swizzledMethodSEL,直接exchange;
//若子类没有实现时,读取父类的方法实现,再添加到子类上,
//如果添加成功,exchange实现,否则不交换
BOOL isLocal = [[self class] isLocallyDefinedMethod:dis_swizzledMethod onClass:class];
if (isLocal) {
Method dis_originMethod = class_getInstanceMethod(class, originMethodSEL);
method_exchangeImplementations(dis_originMethod, dis_swizzledMethod);
}else{
if (class_addMethod(class,
swizzledMethodSEL,
class_getMethodImplementation(class, swizzledMethodSEL),
method_getTypeEncoding(class_getInstanceMethod(class, swizzledMethodSEL)))) {
dis_swizzledMethod = class_getInstanceMethod(class, swizzledMethodSEL);
Method dis_originMethod = class_getInstanceMethod(class, originMethodSEL);
method_exchangeImplementations(dis_originMethod, dis_swizzledMethod);
}
}
SEL swizzleMethodSEL = NSSelectorFromString(@"yher_collectionViewDidSelectItemAtIndexPath");
Method originMethod = class_getInstanceMethod(delegateClass, originMethodSEL);
Class class = GetSelectorInsClass(delegateClass,originMethodSEL,originMethod);
if (class_addMethod(class, swizzleMethodSEL, (IMP)yher_collectionViewDidSelectItemAtIndexPath, "v@:@@")) {
Method swizzleMethod = class_getInstanceMethod(class, swizzleMethodSEL);
method_exchangeImplementations(originMethod, swizzleMethod);
}
} @catch (NSException *exception) {
... ... @@ -139,4 +123,15 @@ void yher_collectionViewDidSelectItemAtIndexPath(id self, SEL _cmd, id collectio
}
}
Class GetSelectorInsClass(Class hclass, SEL sel, Method sel_method) {
Class super_class = [hclass superclass];
if (!super_class) {
return hclass;
}
Method method = class_getInstanceMethod(super_class, sel);
if (method != sel_method) {
return hclass;
}
return GetSelectorInsClass(super_class, sel, sel_method);
}
@end
... ...