为了减少这个应用程序中的剪切和粘贴代码,我试图传递类名,以便告诉方法应该以哪种方式处理某些数据。我有以下内容:
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
错误。推荐的修复程序都会导致其他问题。
第一个建议是在类名后面添加()
构造函数,会在这些行上引发新的错误:Cannot convert value of type 'OneClass' to expected argument type 'AnyClass' (aka 'AnyObject.Type')
采取第二个建议并将它们更改为OneClass.self
和TwoClass.self
可以消除解析器错误,但是当我执行代码时,它只会永远运行..永远不会出错,永远不会完成。< / p>
我在其他地方发现了一项建议,建议我应将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'
。
显然我没有把关于传递类型作为参数传到这里,但是我所做的谷歌搜索都没有让我找到解释我所看到的问题的东西。
答案 0 :(得分:1)
通用的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
}
}
答案 1 :(得分:1)
要使其正常运行,您必须在init
进行类型转换后在cls
上致电NSObject.Type
。此外,x.name
仅在cls
类类型包含该特定属性时才有效。这就是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
}
}
使用doStuff
ClassType.self
print(z.doStuff(withClass: OneClass.self))
print(z.doStuff(withClass: TwoClass.self))
如果您仍然遇到任何问题,请告诉我。