Skip to content

Commit

Permalink
Enforcing class objects as arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
adamszedelyi committed Mar 5, 2017
1 parent 7f83ade commit fd3055d
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 26 deletions.
8 changes: 4 additions & 4 deletions ASHook/ASHook+BlockInsert.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 11 additions & 10 deletions ASHook/ASHook+BlockInsert.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@interface ASHook ()

+ (void)swizzle:(id)swizzleTarget
+ (void)swizzle:(Class)swizzleTarget
selector:(SEL)originalSelector
newSelector:(SEL)newSelector
originalMethod:(Method)originalMethod
Expand All @@ -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) {
Expand All @@ -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";
Expand Down
8 changes: 4 additions & 4 deletions ASHook/ASHook+MethodSwizzler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 9 additions & 8 deletions ASHook/ASHook+MethodSwizzler.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@ @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];
}

#pragma mark - Private methods

+ (void)swizzle:(id)target
+ (void)swizzle:(Class)target
selector:(SEL)originalSelector
newSelector:(SEL)newSelector
originalMethod:(Method)originalMethod
Expand Down
5 changes: 5 additions & 0 deletions ASHookDemo/ASHookDemo/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit fd3055d

Please sign in to comment.