传递 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.self
和 TwoClass.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))
如果您仍然遇到任何问题,请告诉我。
为了减少此应用程序中的剪切和粘贴代码,我尝试传递 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.self
和 TwoClass.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))
如果您仍然遇到任何问题,请告诉我。