TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | Jun 2016 |
Maintained by Alexey Belkevich.
OCFuntime is a toolkit for Objective-C runtime.
Method implementation changing allows to run block of code on corresponding method call. Don't be confused with method swizzling.
Instance method implementation block should conform signature:
method_return_type ^(id selfInstance, arg1_type arg1, arg2_type arg2, ...)
Class method implementation block should conform signature:
method_return_type ^(Class theClass, arg1_type arg1, arg2_type arg2, ...)
Installation
Add pod 'OCFuntime/Methods'
to Podfile
Example
@interface MyClass : NSObject
- (void)someInstanceMethod:(NSObject *)someArg;
+ (NSInteger)someClassMethod;
@end
#import "OCFuntime+Methods.h"
...
OCFuntime *funtime = [[OCFuntime alloc] init];
// Change instance method implementation
[funtime changeClass:MyClass.class instanceMethod:@selector(someInstanceMethod:)
implementation:^(MyClass *instance, NSObject *someArg)
{
NSLog(@"Changed instance method with arg %@!", someArg);
}];
// Change class method implementation
[funtime changeClass:MyClass.class classMethod:@selector(someClassMethod)
implementation:^(Class theClass)
{
NSLog(@"Changed class method of %@!", NSStringFromClass(theClass));
return 5;
}];
//Revert method to default implementation
[funtime revertClass:MyClass.class instanceMethod:@selector(someInstanceMethod)];
[funtime revertClass:MyClass.class classMethod:@selector(someClassMethod)];
// Revert all methods of class to default implementation
[funtime revertClassMethods:MyClass.class];
// Revert all changed methods to default implementation
[funtime revertAllMethods];
Notes
OCFuntime
instance will be deallocated all changed methods will be reverted to default implementations. To avoid it use Shared Instance of OCFuntime
.NSObject Category
Run method implementation changing on corresponding class with NSObject
category.
Add pod 'OCFuntime/NSObject+OCFMethods'
to Podfile
#import "NSObject+OCFMethods.h"
...
// Change class method implementation
[MyClass changeClassMethod:@selector(someClassMethod) implementation:^
{
NSLog(@"Changed 'someClassMethod'");
return 0;
}];
// Change instance method implementation
[MyClass changeInstanceMethod:@selector(someInstanceMethod)
implementation:^(MyClass *instance, NSObject *someArg)
{
NSLog(@"Called changed method of %@ with arg %@", instance, someArg);
}];
// Revert class method implementation
[MyClass revertClassMethod:@selector(someStaticMethod)];
// Revert instance method implementation
[MyClass revertInstanceMethod:@selector(someMethod)];
// Revert all methods
[MyClass revertMethods];
NSObject+OCFMethods
subspec includes Methods
and Shared
subspecs as dependencies. Don't include them to Podfile.
Property injection allow to use @dynamic
properties as it've been @synthesize
.
And it's the best way to avoid "no synthesized properties in objective-c categories" restriction.
Injection is based on Message Forwarding and Associated Objects.
Installation
Add pod 'OCFuntime/Properties'
to Podfile
Example
@interface SomeClass : NSObject
@property (nonatomic, strong) id objectStrongProperty;
@property (nonatomic, assign) NSInteger integerProperty;
@end
...
@implementation
@dynamic objectStrongProperty, integerProperty;
@end
...
#import "OCFuntime+Properties.h"
#import "SomeClass.h"
...
// Inject properties
OCFuntime *funtime = [[OCFuntime alloc] init];
[funtime injectClass:SomeClass.class property:@"objectStrongProperty"];
[funtime injectClass:SomeClass.class property:@"integerProperty"];
// Use properties
SomeClass *someInstance = [[SomeClass alloc] init];
someInstance.objectStrongProperty = [[NSObject alloc] init];
someInstance.integerProperty = 5;
// Remove injected property
[funtime removeClass:SomeClass.class property:@"objectStrongProperty"];
// Remove all class injected properties
[funtime removeClassProperties:SomeClass.class];
// Remove all injected properties
[funtime removeAllProperties];
Notes
atomic
properties injected as nonatomic
. It's will be fixed in one of the next releases.OCFuntime
instance will be deallocated all injected properties will be removed. To avoid it use Shared Instance of OCFuntime
.forwardInvocation:
and methodSignatureForSelector:
because of Swizzling.NSObject Category
Run property injection on corresponding class with NSObject
category.
Add pod 'OCFuntime/NSObject+OCFProperties'
to Podfile
#import "NSObject+OCFProperties.h"
...
// Inject properties
[SomeClass injectProperty:@"objectStrongProperty"];
[SomeClass injectProperty:@"integerProperty"];
// Remove property
[SomeClass removeProperty:@"objectStrongProperty"];
// Remove all injected properties of class
[SomeClass removeProperties];
NSObject+OCFProperties
subspec includes Properties
and Shared
subspecs as dependencies. Don't include them to Podfile.
Shared instance
Add pod 'OCFuntime/Shared'
to Podfile
#import "OCFuntime+Shared.h"
...
[OCFuntime.shared changeClass:MyClass.class
instanceMethod:@selector(someMethod)]
implementation:^
{
NSLog(@"Changed someMethod with shared instance")
}];
Default subspec
Default subspec pod 'OCFuntime'
includes all subspecs. Use @import "OCFuntimeHeader.h"
to enable all features of OCFuntime
.
Follow updates @okolodev