Cocoa中有几个系统类是单例,例如UIApplication,NSNotificationCenter。现在,我想找到所有单身的课程,任何建议我怎么能快速找到它们?
我正在开发一个庞大的代码库,我需要将系统单例对象与自定义单例分离。
答案 0 :(得分:7)
Objective-C运行时hackery!有趣!
现在,在我继续之前,我将提出免责声明,我绝不会建议在实际的运输代码中添加这样的内容,如果你这样做,那完全不是我的错。不过,这对于教育目的而言可能很有趣/有趣。
这不是一门精确的科学,因为语言本身并没有“单身”的任何实际概念。基本上,我们只是在寻找具有某些赠品前缀的类方法的Objective-C类。如果我们找到其中一个,那么我们很有可能拥有一个单身人士。
考虑到这一点:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
static BOOL ClassIsSingleton(Class class) {
unsigned int methodCount = 0;
Method *methods = class_copyMethodList(object_getClass(class), &methodCount);
@try {
for (unsigned int i = 0; i < methodCount; i++) {
Method eachMethod = methods[i];
// only consider class methods with no arguments
if (method_getNumberOfArguments(eachMethod) != 2) {
continue;
}
char *returnType = method_copyReturnType(eachMethod);
@try {
// only consider class methods that return objects
if (strcmp(returnType, @encode(id)) != 0) {
continue;
}
}
@finally {
free(returnType);
}
NSString *name = NSStringFromSelector(method_getName(methods[i]));
// look for class methods with telltale prefixes
if ([name hasPrefix:@"shared"]) {
return YES;
} else if ([name hasPrefix:@"standard"]) {
return YES;
} else if ([name hasPrefix:@"default"]) {
return YES;
} else if ([name hasPrefix:@"main"]) {
return YES;
} // feel free to add any additional prefixes here that I may have neglected
}
}
@finally {
free(methods);
}
return NO;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableArray *singletons = [NSMutableArray new];
int classCount = objc_getClassList(NULL, 0);
Class *classes = (Class *)malloc(classCount * sizeof(Class));
@try {
classCount = objc_getClassList(classes, classCount);
for (int i = 0; i < classCount; i++) {
Class eachClass = classes[i];
if (ClassIsSingleton(eachClass)) {
[singletons addObject:NSStringFromClass(eachClass)];
}
}
}
@finally {
free(classes);
}
NSLog(@"Singletons: %@", singletons);
}
return 0;
}