Skip to content

Instantly share code, notes, and snippets.

@phausler
Last active December 20, 2015 02:49
Show Gist options
  • Save phausler/6058774 to your computer and use it in GitHub Desktop.
Save phausler/6058774 to your computer and use it in GitHub Desktop.
NEVER EVER DO THIS!
struct BlockObject {
Class isa;
int retainCount;
struct BlockObject *(^alloc)();
struct BlockObject *(^init)();
struct BlockObject *(^retain)();
void (^release)();
struct BlockObject *(^autorelease)();
void (^dealloc)();
} BlockObject = {
.alloc = ^() {
struct BlockObject *self = malloc(sizeof(struct BlockObject));
static int block_id = 0;
char *name = NULL;
asprintf(&name, "BlockObject%d", block_id);
block_id = __sync_add_and_fetch(&block_id, 1);
self->isa = objc_allocateClassPair(objc_getClass("NSObject"), name, sizeof(BlockObject) - sizeof(Class));
free(name);
class_addMethod(self->isa, @selector(retain), imp_implementationWithBlock(^(struct BlockObject *self){
return self->retain();
}), "@:@");
class_addMethod(self->isa, @selector(release), imp_implementationWithBlock(^(struct BlockObject *self){
self->release();
}), "v:@");
objc_registerClassPair(self->isa);
self->retainCount = 0;
self->init = Block_copy(^() {
return self;
});
self->retain = Block_copy(^() {
self->retainCount = __sync_add_and_fetch(&self->retainCount, 1);
return self;
});
self->release = Block_copy(^() {
self->retainCount = __sync_add_and_fetch(&self->retainCount, -1);
if (self->retainCount < 0) {
self->dealloc(self);
}
});
self->autorelease = Block_copy(^{
return (struct BlockObject *)[(id)self autorelease];
});
self->dealloc = Block_copy(^() {
Block_release(self->init);
Block_release(self->retain);
Block_release(self->release);
Block_release(self->autorelease);
Block_release(self->dealloc);
objc_disposeClassPair(self->isa);
free(self);
});
return self;
}
};
@nmr8acme
Copy link

nmr8acme commented Oct 1, 2013

o_O

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment