答案 0 :(得分:0)
您可以使用
进行测试Map
或
if viewInArray.isKind(of: MyClass) { ... }
但是我认为您不能将Swift转换为在编译时不可用的类。无论如何,您将无法直接调用其任何方法。您可以将其强制转换为某个if viewInArray.isMember(of: MyClass) { ... } // strict class match
子类,然后向其发送任意(未在编译时定义)消息。
答案 1 :(得分:0)
此处的主要错误是您无法as
或is
检查动态类型。您需要具有在编译时已知的静态类型才能使用它。如要说明的那样,您需要在基础NSObject上使用isKind(of:)
或isMember(of:)
。我建议这样做的方法如下:
func firstXibViewOfClass(named classNameString: String) -> NSView? {
// Create an AnyClass object
guard let projectName = Bundle.main.infoDictionary?["CFBundleExecutable"] as? String,
let myClass = NSClassFromString(projectName + "." + classNameString)
else {
return nil
}
// Load the nib
var topLevelObjects: NSArray?
Bundle.main.loadNibNamed(classNameString, owner: nil, topLevelObjects: &topLevelObjects)
// Convert it to NSObjects (since they all are going to be)
guard let nsObjectArray = topLevelObjects as? [NSObject] else { return nil }
// Find the first matching view and return it as an NSView if possible
return nsObjectArray.first(where: {
$0.isKind(of: myClass) // Or isMember(of:) if you want to be strict
}) as? NSView
}
但是,如果不需要包含子类,则可能只想直接检查类名。这摆脱了所有AnyClass的东西:
func firstXibViewOfClass(named classNameString: String) -> NSView? {
// Load the nib
var topLevelObjects: NSArray?
Bundle.main.loadNibNamed(classNameString, owner: nil, topLevelObjects: &topLevelObjects)
// Convert it to NSObjects (since they all are going to be)
guard let nsObjectArray = topLevelObjects as? [NSObject] else { return nil }
// Find the first matching view and return it as an NSView if possible
return nsObjectArray.first(where: { $0.className == classNameString }) as? NSView
}
您当然可以只返回AnyObject?
,但是方法的名称表明您希望它是一个视图,因此应强制执行该方法或重命名该方法。