首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >找到所有单例的可可类吗?

找到所有单例的可可类吗?
EN

Stack Overflow用户
提问于 2017-08-02 06:21:17
回答 1查看 126关注 0票数 3

Cocoa中有几个系统类是单例的,比如UIApplication、NSNotificationCenter。现在,我想要找到所有单例的类,有什么建议可以让我快速找到它们吗?

我正在开发一个巨大的代码库,我需要将系统单例对象与定制的单例对象分开。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-02 07:24:59

Objective-C运行时黑客!有趣的!

现在,在我继续之前,我将提出免责声明,我永远不会建议在实际的发货代码中放入这样的东西,如果你这样做了,这完全不是我的错。不过,出于教育目的,这样做可能会很有趣。

这不是一门精确的科学,因为语言本身并没有任何“单例”的实际概念。基本上,我们只是在寻找那些拥有带有某些免费前缀的类方法的Objective-C类。如果我们找到了其中的一个,很有可能是一个单例。

考虑到这一点:

代码语言:javascript
复制
#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;
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45448562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档