Swift   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了swift – 如何将类类型作为函数参数传递大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我有一个通用的函数,调用一个Web服务,并将JSON响应序列化回一个对象。 class func invokeservice<T>(service: String, withParams params: Dictionary<String, String>, returningClass: AnyClass, completionHandler handler: ((T) -> ())) {
我有一个通用的函数调用一个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 – 如何将类类型作为函数参数传递全部内容,希望文章能够帮你解决swift – 如何将类类型作为函数参数传递所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。