1#include "../objc/runtime.h" 2#include "../objc/blocks_runtime.h" 3#include <assert.h> 4#include <stdio.h> 5#include <stdlib.h> 6 7struct big 8{ 9 int a, b, c, d, e; 10}; 11 12#ifdef __has_attribute 13#if __has_attribute(objc_root_class) 14__attribute__((objc_root_class)) 15#endif 16#endif 17@interface Foo @end 18@implementation Foo @end 19@interface Foo (Dynamic) 20+(int)count: (int)i; 21+(struct big)sret; 22@end 23 24 25int main(void) 26{ 27 __block Class cls = objc_getClass("Foo"); 28 __block int b = 0; 29 void* blk = ^(id self, int a) { 30 assert(self == cls); 31 b += a; 32 return b; }; 33 blk = Block_copy(blk); 34 IMP imp = imp_implementationWithBlock(blk); 35 char *type = block_copyIMPTypeEncoding_np(blk); 36 assert(NULL != type); 37 class_addMethod((objc_getMetaClass("Foo")), @selector(count:), imp, type); 38 assert(2 == ((int(*)(id,SEL,int))imp)(cls, @selector(count:), 2)); 39 free(type); 40 assert(4 == [Foo count: 2]); 41 assert(6 == [Foo count: 2]); 42 assert(imp_getBlock(imp) == (blk)); 43 IMP imp2 = imp_implementationWithBlock(blk); 44 assert(imp != imp2); 45 imp_removeBlock(imp); 46 assert(imp_getBlock(imp) != (blk)); 47 48 blk = ^(id self) { 49 assert(self == cls); 50 struct big b = {1, 2, 3, 4, 5}; 51 return b; 52 }; 53 imp = imp_implementationWithBlock(blk); 54 assert(imp && "Can't make sret IMP"); 55 type = block_copyIMPTypeEncoding_np(blk); 56 assert(NULL != type); 57 class_addMethod((objc_getMetaClass("Foo")), @selector(sret), imp, type); 58 free(type); 59 struct big s = [Foo sret]; 60 assert(s.a == 1); 61 assert(s.b == 2); 62 assert(s.c == 3); 63 assert(s.d == 4); 64 assert(s.e == 5); 65 return 0; 66} 67