Ios 在Objective-C中的Swift类上调用NSStringFromClass将返回模块损坏的名称
我知道如何在Swift中获得objective-c类的可读类名 我想要实现的是从objective-c内部获取Swift类的可读类名,而不会将类名与模块弄乱 因此,如果我有一门快速课程:Ios 在Objective-C中的Swift类上调用NSStringFromClass将返回模块损坏的名称,ios,objective-c,swift,xcode6,Ios,Objective C,Swift,Xcode6,我知道如何在Swift中获得objective-c类的可读类名 我想要实现的是从objective-c内部获取Swift类的可读类名,而不会将类名与模块弄乱 因此,如果我有一门快速课程: class Foo: NSObject{} @objc(YourClassName) class YourClassName: NSObject { } 然后在Objective-C中,我希望使用方便的NSStringFromClass将类名转换为字符串 我希望NSStringFromClass([Fo
class Foo: NSObject{}
@objc(YourClassName)
class YourClassName: NSObject {
}
然后在Objective-C中,我希望使用方便的NSStringFromClass将类名转换为字符串
我希望NSStringFromClass([Foo class])
返回@“Foo”
,但它返回@“Bar.Foo”
,其中Bar
是模块名
我遇到了这个问题,但它似乎有点杂乱无章,有没有更好的办法?最好不要在字符串中手动键入类名。在SWIFT 2.1之前:
只需将@objc(YourClassName)
放入您的swift类:
class Foo: NSObject{}
@objc(YourClassName)
class YourClassName: NSObject {
}
您可以像这样使用NSStringFromClass:
NSStringFromClass(YourClassName.self)
它也应该从Objective-C开始工作
SWIFT 2.1 在Swift 2.1中,对该答案的评论指出,这已足够:
class YourClassName: NSObject {
}
只需使用:
var str = String(YourClassName)
不过,我自己还没有从Objective-C代码中测试过这一点
有一些编辑建议希望在Swift 4中使用此选项:
var str = String(describing: YourClassName.self)
但是我还没有从Objective-C测试过这个问题。之所以得到“Bar.Foo”,是因为swift是一种名称空间语言。我假设您在其中运行的应用程序名为Bar。因此,您可以通过以下方式获得类名:
let nameSpaceClassName = NSStringFromClass(Foo)
let className = nameSpaceClassName.componentsSeparatedByString(".").last! as String
编辑:
以上是一个非常古老的答案,应根据Swift库中最近的介绍进行更改(至少从3和4开始)。请注意,以下使用镜像接口来正确提取类的元数据:
import Foundation
/// A protocol that provides demangled information regarding core Swift structure naming components in a usable way.
public protocol StructureNameReflectable {
/**
An ordered list of domain named based components for the structure.
- Example: A simple example would be:
```
class Dog: NSObject {
class Retriever: NSOjbect {}
}
let retriever = Retriever()
```
`retriever.structuredName` would output `["Dog", "Retriever"]`
*/
static var structureNameComponents: [String] { get }
///Outputs the structure's name in a string based form minus namespacing
static var structureName: String { get }
///Outputs the structure's name in a string based form with namespacing
static var namespacedStructureName: String { get }
///Outputs the bundle the structure is contained in
static var bundle: Bundle { get }
}
extension StructureNameReflectable {
public static var structureNameComponents: [String] {
let type = Mirror(reflecting: self).subjectType
let structureNameComponents = "\(type)".components(separatedBy: ".")
return structureNameComponents
}
public static var structureName: String {
var structureNameComponents = self.structureNameComponents
if structureNameComponents.count > 1 && structureNameComponents.last == "Type" {
structureNameComponents.removeLast()
}
return structureNameComponents.last!
}
public static var namespacedStructureName: String {
return structureNameComponents.joined(separator: ".")
}
}
extension StructureNameReflectable where Self: NSObject {
public static var bundle: Bundle {
return Bundle(for: self)
}
public static var className: String {
return structureName
}
}
extension NSObject: StructureNameReflectable { }
希望以上内容能为持续不正确使用字符串(description:)
提供指导,请使用Swift 2.0:
self.description().componentsSeparatedByString(".").last!
Swift 2.1中的工作解决方案是
String(MyClass)
在objective-c中,您的最佳选择是:
NSString *yourCellName = NSStringFromClass([yourCell class]).pathExtension;
NSStringFromClass的Swift 5.1解决方案 如果需要类名的字符串描述(例如
CustomTableViewCell
),请使用:
在最新的Swift上,以下内容对我有效:
NSStringFromClass(type(of: yourClass!.self))
模块前缀名称是可读的类名。如果删除模块前缀,可能会有多个同名的类。您应该保留它。@GregParker不适用于故事板或核心数据,因此在某些情况下值得这样做:)类似于nibWithName:NSStringFromClass:-nibWithName:的建议是也使用模块前缀名作为文件名。@GregParker您有任何链接可以指向它吗?这似乎击败了模块的整体概念,因为我认为我们已经放弃了3个字母的前缀,似乎有点过分了,必须用模块名来命名所有东西。如果您更改了模块名,那么这将是一个巨大的必要重构。或者,您也可以调用nameSpaceClassName.pathExtension来获取类名,但我仍然喜欢接受的答案:)但是,
String(Foo)
更合适。@Dawnson不,不是,这将打印出描述,而该描述永远不能保证是类名或在该结构中格式化。假设时显式和非显式是有区别的如果这是硬文档化的预期行为,那么这是一件事,如果它“只适用于”特定的swift版本,这是一个不好的假设。此外,似乎您仍然继承了NSObjectFYI:当设置@objc(YourClassName)时
对于在xib文件中设置的UIView
的子类,我必须重新设置该类。您可能需要按照最新接受的语法@DanielGalasko更新答案,谢谢。它似乎在操场上工作得很好。您也在objective-C中尝试过吗?嗯,这与Obj-C无关。只是在Swift 2.1中,接受的语法是String(ClassName)
overNSStringFromClass(ClassName)
回答的问题是:“那么在Objective-C内部,我希望使用方便的NSStringFromClass将类名转换为字符串。”因此,它与Objective-C完全相关。类名不是文件,它们没有路径或扩展名。string.init(反射:t)
是init函数原型,另请参见string.init(t)
。我不知道为什么有人否决了这个答案,并且没有给出理由。