diff --git a/ASHook/ASHook+BlockInsert.h b/ASHook/ASHook+BlockInsert.h index 0f20a98..2c12e23 100644 --- a/ASHook/ASHook+BlockInsert.h +++ b/ASHook/ASHook+BlockInsert.h @@ -14,20 +14,20 @@ * Runs the given block on the target just before the given selector gets called. * * @param block The block that will run. - * @param hookTarget The instance or class where the selector can be found. + * @param hookTarget The class object where the selector can be found. * @param hookSelector The original selector that will trigger the block. * */ -+ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(id)hookTarget beforeInstanceSelector:(SEL)hookSelector; ++ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(Class)hookTarget beforeInstanceSelector:(SEL)hookSelector; /** * Runs the given block on the target just before the given selector gets called. * * @param block The block that will run. - * @param hookTarget The instance or class where the selector can be found. + * @param hookTarget The class object where the selector can be found. * @param hookSelector The original selector that will trigger the block. * */ -+ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(id)hookTarget beforeClassSelector:(SEL)hookSelector; ++ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(Class)hookTarget beforeClassSelector:(SEL)hookSelector; @end diff --git a/ASHook/ASHook+BlockInsert.m b/ASHook/ASHook+BlockInsert.m index 06d77f4..9a677ad 100644 --- a/ASHook/ASHook+BlockInsert.m +++ b/ASHook/ASHook+BlockInsert.m @@ -13,7 +13,7 @@ @interface ASHook () -+ (void)swizzle:(id)swizzleTarget ++ (void)swizzle:(Class)swizzleTarget selector:(SEL)originalSelector newSelector:(SEL)newSelector originalMethod:(Method)originalMethod @@ -25,18 +25,19 @@ @implementation ASHook (BlockInsert) #pragma mark - Public methods -+ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(id)hookTarget beforeInstanceSelector:(SEL)hookSelector { - id target = [hookTarget class]; - Method originalMethod = class_getInstanceMethod(target, hookSelector); - SEL newSelector = [self insertBlock:block onTarget:target originalSelector:hookSelector originalMethod:originalMethod]; ++ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(Class)hookTarget beforeInstanceSelector:(SEL)hookSelector { + assert((hookTarget && hookTarget == [hookTarget class]) && "Plese use a class as the target."); + Method originalMethod = class_getInstanceMethod(hookTarget, hookSelector); + SEL newSelector = [self insertBlock:block onTarget:hookTarget originalSelector:hookSelector originalMethod:originalMethod]; if (newSelector) { - Method newMethod = class_getInstanceMethod(target, newSelector); - [ASHook swizzle:target selector:hookSelector newSelector:newSelector originalMethod:originalMethod newMethod:newMethod]; + Method newMethod = class_getInstanceMethod(hookTarget, newSelector); + [ASHook swizzle:hookTarget selector:hookSelector newSelector:newSelector originalMethod:originalMethod newMethod:newMethod]; } } -+ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(id)hookTarget beforeClassSelector:(SEL)hookSelector { - id target = object_getClass([hookTarget class]); ++ (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(Class)hookTarget beforeClassSelector:(SEL)hookSelector { + assert((hookTarget && hookTarget == [hookTarget class]) && "Plese use a class as the target."); + id target = object_getClass(hookTarget); Method originalMethod = class_getClassMethod(target, hookSelector); SEL newSelector = [self insertBlock:block onTarget:target originalSelector:hookSelector originalMethod:originalMethod]; if (newSelector) { @@ -49,7 +50,7 @@ + (void)runBlock:(void (^)(__unsafe_unretained id _self))block onTarget:(id)hook /*! @brief Creating and adding a new implementation for the original method with the block included. */ + (SEL)insertBlock:(void (^)(__unsafe_unretained id _self))block - onTarget:(id)target + onTarget:(Class)target originalSelector:(SEL)originalSelector originalMethod:(Method)originalMethod { NSString *swizzledMethodSuffix = @"_ASMethodSwizzled"; diff --git a/ASHook/ASHook+MethodSwizzler.h b/ASHook/ASHook+MethodSwizzler.h index 551a4a1..71751fa 100644 --- a/ASHook/ASHook+MethodSwizzler.h +++ b/ASHook/ASHook+MethodSwizzler.h @@ -13,21 +13,21 @@ /** * Replaces the implementations of the two given instance selectors in a class object. * - * @param swizzleTarget The target (instance or class) where you want to replace selectors. + * @param swizzleTarget The target class object where you want to replace selectors. * @param originalSelector The original selector that is to be replaced. * @param newSelector The new selector will replace the original selector's implementation. * */ -+ (void)swizzle:(id)swizzleTarget instanceSelector:(SEL)originalSelector withInstanceSelector:(SEL)newSelector; ++ (void)swizzle:(Class)swizzleTarget instanceSelector:(SEL)originalSelector withInstanceSelector:(SEL)newSelector; /** * Replaces the implementations of the two given class selectors in a class object. * - * @param swizzleTarget The target (instance or class) where you want to replace selectors. + * @param swizzleTarget The target class object where you want to replace selectors. * @param originalSelector The original selector that is to be replaced. * @param newSelector The new selector will replace the original selector's implementation. * */ -+ (void)swizzle:(id)swizzleTarget classSelector:(SEL)originalSelector withClassSelector:(SEL)newSelector; ++ (void)swizzle:(Class)swizzleTarget classSelector:(SEL)originalSelector withClassSelector:(SEL)newSelector; @end diff --git a/ASHook/ASHook+MethodSwizzler.m b/ASHook/ASHook+MethodSwizzler.m index 373bfb6..ad0765d 100644 --- a/ASHook/ASHook+MethodSwizzler.m +++ b/ASHook/ASHook+MethodSwizzler.m @@ -14,15 +14,16 @@ @implementation ASHook (MethodSwizzler) #pragma mark - Public methods -+ (void)swizzle:(id)swizzleTarget instanceSelector:(SEL)originalSelector withInstanceSelector:(SEL)newSelector { - id target = [swizzleTarget class]; - Method originalMethod = class_getInstanceMethod(target, originalSelector); - Method newMethod = class_getInstanceMethod(target, newSelector); - [self swizzle:target selector:originalSelector newSelector:newSelector originalMethod:originalMethod newMethod:newMethod]; ++ (void)swizzle:(Class)swizzleTarget instanceSelector:(SEL)originalSelector withInstanceSelector:(SEL)newSelector { + assert((swizzleTarget && swizzleTarget == [swizzleTarget class]) && "Plese use a class as the target."); + Method originalMethod = class_getInstanceMethod(swizzleTarget, originalSelector); + Method newMethod = class_getInstanceMethod(swizzleTarget, newSelector); + [self swizzle:swizzleTarget selector:originalSelector newSelector:newSelector originalMethod:originalMethod newMethod:newMethod]; } -+ (void)swizzle:(id)swizzleTarget classSelector:(SEL)originalSelector withClassSelector:(SEL)newSelector { - id target = object_getClass([swizzleTarget class]); ++ (void)swizzle:(Class)swizzleTarget classSelector:(SEL)originalSelector withClassSelector:(SEL)newSelector { + assert((swizzleTarget && swizzleTarget == [swizzleTarget class]) && "Plese use a class as the target."); + id target = object_getClass(swizzleTarget); Method originalMethod = class_getClassMethod(target, originalSelector); Method newMethod = class_getClassMethod(target, newSelector); [self swizzle:target selector:originalSelector newSelector:newSelector originalMethod:originalMethod newMethod:newMethod]; @@ -30,7 +31,7 @@ + (void)swizzle:(id)swizzleTarget classSelector:(SEL)originalSelector withClassS #pragma mark - Private methods -+ (void)swizzle:(id)target ++ (void)swizzle:(Class)target selector:(SEL)originalSelector newSelector:(SEL)newSelector originalMethod:(Method)originalMethod diff --git a/ASHookDemo/ASHookDemo/AppDelegate.m b/ASHookDemo/ASHookDemo/AppDelegate.m index 0704b2e..be7dba0 100644 --- a/ASHookDemo/ASHookDemo/AppDelegate.m +++ b/ASHookDemo/ASHookDemo/AppDelegate.m @@ -34,6 +34,11 @@ + (void)initialize { [ASHook runBlock:^(__unsafe_unretained id _self) { NSLog(@"alloc will run on %@ - will there be any funny messages in it?", _self); } onTarget:[EvilSingleton class] beforeClassSelector:@selector(alloc)]; + + // Example 5: Lifecycle + [ASHook swizzle:[[EvilSingleton sharedInstance] class] instanceSelector:@selector(shouldSingletonsBeUsedInAproject) withInstanceSelector:@selector(printNever)]; + NSLog(@"Should I use singletons?"); + [[EvilSingleton sharedInstance] shouldSingletonsBeUsedInAproject]; } - (void)applicationDidFinishLaunching:(NSNotification *)notification {