当前位置 : 主页 > 手机开发 > ios >

ios – 查找所有单例的可可类?

来源:互联网 收集:自由互联 发布时间:2021-06-11
Cocoa中有几个系统类是单例,例如UIApplication,NSNotificationCenter.现在,我想找到所有单身的课程,任何建议我怎么能快速找到它们? 我正在开发一个庞大的代码库,我需要将系统单例对象与自定
Cocoa中有几个系统类是单例,例如UIApplication,NSNotificationCenter.现在,我想找到所有单身的课程,任何建议我怎么能快速找到它们?

我正在开发一个庞大的代码库,我需要将系统单例对象与自定义单例分离.

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;
}
网友评论