swift – 如何将类类型作为函数参数传递

前端之家收集整理的这篇文章主要介绍了swift – 如何将类类型作为函数参数传递前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个通用的函数调用一个Web服务,并将JSON响应序列化回一个对象。
class func invokeService<T>(service: String,withParams params: Dictionary<String,String>,returningClass: AnyClass,completionHandler handler: ((T) -> ())) {

            /* Construct the URL,call the service and parse the response */
}

我想要完成的是相当于这个Java代码

public <T> T invokeService(final String serviceURLSuffix,final Map<String,String> params,final Class<T> classTypeToReturn) {
}

首先,我的方法签名我想要完成什么?更具体地说,是指定AnyClass作为参数类型正确的事情吗?

此外,当调用方法时,我传递MyObject.self作为returningClass值,但我得到一个编译错误“无法转换表达式的类型'()’类型’字符串’

CastDAO.invokeService("test",withParams: ["test" : "test"],returningClass: CityInfo.self) { cityInfo in /*...*/

}

任何帮助将不胜感激。

谢谢

编辑:我尝试使用object_getClass,由holex提及,现在我得到这个错误:“类型’CityInfo.Type’不符合协议’AnyObject’”。需要做什么以符合协议?

class CityInfo : NSObject {

    var cityName: String?
    var regionCode: String?
    var regionName: String?
}
你在错误的方式接近它:在Swift,不同于Objective-C,类有特定的类型,甚至有一个继承层次结构(也就是说,如果B类继承自A,那么B.Type也继承自A.Type):
class A {}
class B: A {}
class C {}

// B inherits from A
let object: A = B()

// B.Type also inherits from A.Type
let type: A.Type = B.self

// Error: 'C' is not a subtype of 'A'
let type2: A.Type = C.self

这就是为什么你不应该使用AnyClass,除非你真的想允许任何类。在这种情况下,正确的类型将是T.Type,因为它表达了returningClass参数和闭包的参数之间的链接

事实上,使用它而不是AnyClass允许编译器正确地推断方法调用中的类型:

class func invokeService<T>(service: String,returningClass: T.Type,completionHandler handler: ((T) -> ())) {
    // The compiler correctly infers that T is the class of the instances of returningClass
    handler(returningClass())
}

现在有一个问题,构造一个T的实例传递给处理程序:如果你现在尝试并运行代码,编译器会抱怨T不是可构造的()。正确的是:T必须明确地限制要求它实现一个特定的初始化器。

这可以通过像下面这样的协议来完成:

protocol Initable {
    init()
}

class CityInfo : NSObject,Initable {
    var cityName: String?
    var regionCode: String?
    var regionName: String?

    // Nothing to change here,CityInfo already implements init()
}

然后你只需要改变invokeService的泛型约束,从< T>到< T:Initable&gt ;. 小费 如果你得到奇怪的错误,如“无法将表达式的类型()’转换为类型”字符串“,通常有用的是将方法调用的每个参数移动到自己的变量。它有助于缩小导致错误代码并揭示类型推断问题:

let service = "test"
let params = ["test" : "test"]
let returningClass = CityInfo.self

CastDAO.invokeService(service,withParams: params,returningClass: returningClass) { cityInfo in /*...*/

}

现在有两种可能性:错误移动到其中一个变量(这意味着错误的部分存在)或者你得到一个隐藏的消息,如“无法将表达式的type()转换为类型($ T6) – >($ T6)→> $ T5“。

后一个错误的原因是编译器不能推断你写的类型。在这种情况下,问题是T只用在闭包的参数中,而你传递的闭包不指示任何特定类型,所以编译器不知道要推断什么类型。通过更改returningClass的类型以包括T,您可以为编译器提供一种确定通用参数的方法

猜你在找的Swift相关文章