get objc subclasses via private runtime info
#include <objc/objc-runtime.h> | |
// from objc_runtime_new.h with some simplifications | |
#if __LP64__ | |
typedef uint32_t mask_t; | |
#define FAST_DATA_MASK 0x00007ffffffffff8UL | |
#else | |
typedef uint64_t mask_t; | |
#define FAST_DATA_MASK 0xfffffffcUL | |
#endif | |
struct class_rw_t { | |
// flag, version, ro, methods, properties, protocols | |
uint8_t __placeholder[sizeof(uint32_t) * 2 + sizeof(void*) * 4]; | |
Class firstSubClass; | |
Class nextSiblingClass; | |
const char* demangleName; | |
}; | |
struct class_data_bits_t { | |
uintptr_t bits; | |
class_rw_t* data() { | |
return (class_rw_t*)(bits & FAST_DATA_MASK); | |
} | |
}; | |
struct objc_class_t { | |
Class isa; | |
Class superclass; | |
// buckets, masks = cache_t | |
uint8_t __placeholder[sizeof(void*) + sizeof(mask_t) * 2]; | |
class_data_bits_t dataBits; | |
Class getFirstSubClass() { | |
return dataBits.data()->firstSubClass; | |
} | |
Class getNextSiblingClass() { | |
return dataBits.data()->nextSiblingClass; | |
} | |
}; | |
void print_subclass_tree(Class cls, int level) | |
{ | |
objc_class_t* rt_cls = (__bridge objc_class_t*)cls; | |
Class subClass = rt_cls->getFirstSubClass(); | |
while(subClass) | |
{ | |
for(int i=0; i<level; ++i) | |
printf(" "); | |
printf("%s\n", class_getName(subClass)); | |
print_subclass_tree(subClass, level + 1); | |
subClass = ((__bridge objc_class_t*)subClass)->getNextSiblingClass(); | |
} | |
} | |
int main(int argc, const char * argv[]) { | |
Class cls = objc_getClass("NSObject"); | |
print_subclass_tree(cls, 0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment