NSClassFromString为嵌套类返回nil [英] NSClassFromString returning nil for nested class

查看:44
本文介绍了NSClassFromString为嵌套类返回nil的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过使用字符串实例化一个类,但是我遇到了问题.那就是我想要做的:

I want to instantiate a class by using a string but I'm having problems. That's what I try to do:

let aClass = NSClassFromString("MyApp.Outer.Inner") as! SomeProtocol.Type
....
public class Outer {
    public class Inner: SomeProtocol {
        init() {...}
    }
}

那很崩溃(因为NSClassFromString返回nil

That's crashing (because NSClassFromString returns nil

但这是有效的:

let aClass = NSClassFromString("MyApp.Inner") as! SomeProtocol.Type
....
public class Inner: SomeProtocol {
    init() {...}
}

NSClassFromString对嵌套类不起作用吗?

Doesn't NSClassFromString work for nested classes?

背景: 我有许多内部"类用作模板来创建对象(而不是将它们存储在.plist文件中,这很烦人).我想将它们封装在外部"类中,以更好地组织它们.

Background: I have many "inner" classes that I use as templates to create objects (instead of storing them in .plist files, which is kind of annoying). I want to encapsulate them in an "Outer" class to have them better organised.

感谢您的帮助:)

我看到了一个似乎与之重复的问题.但这不是一个可行的解决方案:

I saw the question that this seems to be a duplicate of. But that's not a viable solution:

(请注意,此代码片段不会自己运行-必须在过程中的某个位置至少引用一次AB类,才能在ObjC运行时中进行注册.这就像将let t = AB放入一样简单.自我在应用程序的启动代码中的某个位置.)

(Note this snippet won't run by itself -- the class A.B has to be referenced at least once somewhere in your process in order to be registered with the ObjC runtime. This could be as simple as putting let t = A.B.self somewhere in your app's startup code.)

我正在使用NSClassFromString进行这种方法,因为我想避免为我创建的每个内部类添加过多的内容.我不想一直将此添加到我的启动代码中.

I'm doing this approach with NSClassFromString because I want to avoid adding too much stuff for every inner class I create. I don't want to constantly add this to my startup code.

推荐答案

如果运行此代码:

import Foundation

class Outer: NSObject {
    class Inner: NSObject {}
}

print(NSStringFromClass(Outer.Inner.self))

您将获得以下内容:

_TtCC8Untitled5Outer5Inner

如您所见,嵌入式类的名称与您期望的方式有所不同.我相信改写格式也是未记录的,因此您不能依靠它在以后的某些Swift版本中不会改变.

As you can see, embedded classes have their names mangled differently from how you'd expect. I believe the mangling format is undocumented, as well, so you can't rely on this not changing in some future Swift release.

如果需要能够在Objective-C运行时中使用其名称访问类,则可以使用@objc属性为其提供自定义的Objective-C名称.不幸的是,@objc关键字不允许点,但是您可以使用下划线获得类似的效果:

If you need to be able to access a class using its name in the Objective-C runtime, you can use the @objc attribute to give it a custom Objective-C name. Unfortunately, the @objc keyword doesn't allow dots, but you can use underscores for a similar effect:

class Outer: NSObject {
    @objc (Outer_Inner) class Inner: NSObject {}
}

我应该澄清一下,即使指定了@objc关键字,在对Objective-C运行库可用之前,以及在像NSClassFromString()这样的函数可用之前,仍需要通过Swift代码访问内部类.会起作用.

I should clarify that even with the @objc keyword specified, the inner class will still need to be accessed by Swift code before it will be available to the Objective-C runtime, and thus before functions like NSClassFromString() will work.

这篇关于NSClassFromString为嵌套类返回nil的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆