Ключевая ошибка здесь в том, что вы не можете as
или is
проверить динамический тип.Вам нужно иметь статический тип, известный во время компиляции, чтобы использовать это.Как отмечает Pointum, вам нужно использовать isKind(of:)
или isMember(of:)
для базового NSObject.Вот как я бы порекомендовал сделать это:
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?
, но название метода предполагает, что вы ожидаете, что это будет представление, поэтому вы должны принудительно применить это илипереименуйте метод.