Skip to content

Instantly share code, notes, and snippets.

@volodg
Created April 11, 2013 15:13
Show Gist options
  • Save volodg/5364194 to your computer and use it in GitHub Desktop.
Save volodg/5364194 to your computer and use it in GitHub Desktop.
Dinamic hook of object's method exaple
@interface SimpleHookExampleClass : NSObject
@property (nonatomic) NSUInteger state;
@end
@implementation SimpleHookExampleClass
- (NSUInteger)mutStateOnArg:(NSUInteger)arg
{
return _state * arg;
}
@end
- (void)testSimpleExample
{
//test observing existing method
{
__block BOOL hookWasCalled = NO;
NSUInteger originalArg = 12;
NSUInteger originalState = 2;
typedef NSUInteger(^BlockObserver)(id _self, NSUInteger arg);
id observer = ^BlockObserver(BlockObserver(^previousImplementationGetter)(void)) {
return ^NSUInteger(id _self, NSUInteger arg) {
hookWasCalled = YES;
BlockObserver previousImplementation = previousImplementationGetter();
NSUInteger previousResult = previousImplementation(_self, arg);
STAssertEquals((NSUInteger)24, previousResult, nil);
STAssertEquals((NSUInteger)12, arg, nil);
return 11;
};
};
SimpleHookExampleClass *testObject = [SimpleHookExampleClass new];
testObject.state = originalState;
[testObject addMethodHook:observer
selector:@selector(mutStateOnArg:)];
NSUInteger result = [testObject mutStateOnArg:originalArg];
STAssertEquals((NSUInteger)11, result, nil);
STAssertTrue(hookWasCalled, nil);
}
//test normal call
{
NSUInteger originalArg = 10;
NSUInteger originalState = 3;
__weak TestClassToTestHooks *weakTestObject;
@autoreleasepool
{
TestClassToTestHooks *testObject = [TestClassToTestHooks new];
weakTestObject = testObject;
testObject.state = originalState;
id result = [testObject returnObjectForIntegerPoint:NSMakeRange(2, 3) arg:originalArg];
STAssertEqualObjects([@(originalArg * originalState) stringValue], result, nil);
}
STAssertNil(weakTestObject, nil);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment