传递 class 类型以在方法内部使用

Pass a class type for use inside a method

为了减少此应用程序中的剪切和粘贴代码,我尝试传递 class 名称以告知方法它应该以何种方式处理某些数据。我有类似以下内容:

class MyClass : NSObject {
    var name : String = ""
}

class OneClass : MyClass {
    override init() {
        super.init()
        self.name = "One"
    }
}

class TwoClass : MyClass {
    override init() {
        super.init()
        self.name = "Two"
    }
}


class Thing : NSObject {
    func doStuff(withClass cls: AnyClass) -> String {
        let x = cls.init()
        return x.name
    }
}

let z = Thing()
print(z.doStuff(withClass: OneClass))
print(z.doStuff(withClass: TwoClass))

传递 withClass cls: AnyClass 解析器促使我将 let x = cls() 更改为 let x = cls.init()。但是最后两行出现 Expected member name or constructor call after type name 错误。建议的修复都会导致其他问题。

第一个建议,在 class 名称后添加 () 构造函数,导致这些行出现新错误:Cannot convert value of type 'OneClass' to expected argument type 'AnyClass' (aka 'AnyObject.Type')

采纳第二个建议并将它们更改为 OneClass.selfTwoClass.self 消除了解析器错误,但是当我执行代码时它会永远运行..永远不会出错,也永远不会完成.

我在其他地方找到了建议我应该更改 Thing.doStuff() 参数以期望 MyClass 而不是 AnyClass,但这会导致另一组新问题。

首先,解析器开始抱怨 cls.init() 调用,它建议的一系列修复最终导致一些毫无意义的事情:let x = cls.type(of:;; init)()。解析器在建议循环中结束,它不断在语句中间添加更多分号。

其次,我返回到在最后两行调用 doStuff() 时键入不匹配错误:Cannot convert value of type 'OneClass.Type' to expected argument type 'MyClass'.

这里显然有一些关于将类型作为参数传递的内容我没有得到,但是 none 我所做的谷歌搜索让我找到了一些可以解释我所看到的问题的东西。

通用 Swift 方式如何。

代码将泛型类型 T 限制为 MyClass,因为它必须具有 name 属性。

class MyClass : NSObject {
    var name : String

    override required init() {
        self.name = ""
        super.init()
    }
}

class OneClass : MyClass {
    required init() {
        super.init()
        self.name = "One"
    }
}

class TwoClass : MyClass {
    required init() {
        super.init()
        self.name = "Two"
    }
}


class Thing : NSObject {
    func doStuff<T : MyClass>(withClass cls: T.Type) -> String {
        let x = cls.init()
        return x.name
    }
}

let z = Thing()
print(z.doStuff(withClass: OneClass.self))
print(z.doStuff(withClass: TwoClass.self))

或者使用协议。

protocol Nameable {
    var name : String { get }
    init()
}

class MyClass : NSObject, Nameable { ...

...

class Thing : NSObject {
    func doStuff<T : Nameable>(withClass cls: T.Type) -> String {
        let x = cls.init()
        return x.name
    }
}

要使其正常工作,您必须在将 cls 类型转换为 NSObject.Type 后调用 init。此外,x.name 仅在 cls Class 类型包含特定 属性 时才有效。这就是 x 然后被类型转换为 MyClass.

的原因
class Thing : NSObject
{
    func doStuff(withClass cls: AnyClass) -> String?
    {
        let x = (cls as? NSObject.Type)?.init()
        if let x = x as? MyClass
        {
            return x.name
        }
        return nil
    }
}

ClassType.self 调用 doStuff

print(z.doStuff(withClass: OneClass.self))
print(z.doStuff(withClass: TwoClass.self))

如果您仍然遇到任何问题,请告诉我。