Cocoa中有几个系统类是单例的,比如UIApplication、NSNotificationCenter。现在,我想要找到所有单例的类,有什么建议可以让我快速找到它们吗?
我正在开发一个巨大的代码库,我需要将系统单例对象与定制的单例对象分开。
发布于 2017-08-02 07:24:59
Objective-C运行时黑客!有趣的!
现在,在我继续之前,我将提出免责声明,我永远不会建议在实际的发货代码中放入这样的东西,如果你这样做了,这完全不是我的错。不过,出于教育目的,这样做可能会很有趣。
这不是一门精确的科学,因为语言本身并没有任何“单例”的实际概念。基本上,我们只是在寻找那些拥有带有某些免费前缀的类方法的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;
}https://stackoverflow.com/questions/45448562
复制相似问题