Skip to content

Instantly share code, notes, and snippets.

@janodev
Last active December 15, 2015 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janodev/5332644 to your computer and use it in GitHub Desktop.
Save janodev/5332644 to your computer and use it in GitHub Desktop.
Dynamic GCD accessors with resolveInstanceMethod: and dispatch_barrier_async.
#include <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface Hi : NSObject
@end
@implementation Hi {
NSString *something;
}
dispatch_queue_t _queue;
-(instancetype)init {
self = [super init];
if (self){
_queue = dispatch_queue_create("com.example", DISPATCH_QUEUE_CONCURRENT);
}
return self;
}
static id ivarIMP(id self, SEL _cmd) {
__block NSString *localSomething;
dispatch_sync(_queue, ^{
Ivar ivar = class_getInstanceVariable([self class], [NSStringFromSelector(_cmd) UTF8String]);
localSomething = object_getIvar(self, ivar);
});
return localSomething;
}
static void setIvarIMP(id self, SEL _cmd, id value) {
dispatch_barrier_async(_queue, ^{
// ouch, slow block here
const char* sName = sel_getName(_cmd);
size_t len = strlen(sName);
char *name = malloc(len-4);
strncpy(name,sName+3,len-4);
name[0] = tolower(name[0]);
Ivar ivar = class_getInstanceVariable([self class], name);
object_setIvar(self, ivar, value);
});
}
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
NSMutableString *name = [NSStringFromSelector(aSEL) mutableCopy];
if ([name hasPrefix:@"set"]) {
class_addMethod([self class], aSEL, (IMP)setIvarIMP, "v@:@");
} else {
class_addMethod([self class], aSEL,(IMP)ivarIMP, "@@:");
}
return YES;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
id hi = [Hi new];
[hi performSelector:@selector(setSomething:) withObject:@"X"];
NSLog(@"%@",[hi performSelector:@selector(something)]);
// to avoid “No known instance method” use performSelector, @dynamic,
// objc_msgSend, a protocol, a compiler flag or pragma (if there is any).
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment