通过名称

时间:2018-07-30 20:55:26

标签: objective-c swift

我正在解决一个问题,在这个问题中,我有一个混合的代码库和创建范例,其中一个类(在Objective-C中)具有我可以创建和使用的所有类的名称。

以前,代码库完全是Objective-C的,所以当我有一个需要创建的类的名称时,我就去了:

- (Class)sourceClass {
    return NSClassFromString(sourceClassName);
}

现在,我必须支持返回的Swift类。我已经尝试在班级前面使用包名称加上一个点。这不起作用(返回nil):

NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
NSString *classStringName = [NSString stringWithFormat:@"%@.%@", appName, sourceClassName];
return NSClassFromString(classStringName);

我还尝试了一些在网上发现的疯狂格式,也返回nil:

NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
NSString *classStringName = [NSString stringWithFormat:@"_TtC%lu%@%lu%@", appName.length, appName, sourceClassName.length, sourceClassName];
return NSClassFromString(classStringName);

1 个答案:

答案 0 :(得分:0)

尝试使用像这样的运行时来混合和匹配Objective-C和Swift将会很成问题。首先,您所有的Swift类以及所需的任何属性或函数都必须公开给Objective-C。接下来,您发现了命名问题。检查名称的最佳方法是对项目中的所有类进行快速的类转储。这是我的一个项目的一些代码,这些代码扫描捆绑包中的类:

 // Get a reference to your main bundle or the bundle where the Swift classes are.
CFBundle * bundle = //....
NSURL *executableURL = (NSURL *) CFBridgingRelease(CFBundleCopyExecutableURL(bundle));
if (executableURL) {

    STLog(self, @"Scanning executable: %@", executableURL);

    unsigned int count = 0;
    const char** classes = objc_copyClassNamesForImage(executable, &count);
    STLog(self, @"Found %i classes", count);
    if (count == 0) {
        return;
    }

    for(unsigned int i = 0;i < count;i++) {
        Class nextClass = objc_getClass(classes[i]);
        // Print the class name here
    }
}

使用类似的方法应该可以帮助您确保可以看到所要学习的课程并正确命名它们。

最后,让我担心的关于代码描述的概念是使用单个类作为其他所有内容的工厂的概念。这听起来像是一个极度局限和有问题的设计。我建议您花点时间坐下来重新评估一下是否真的是一个好主意。