带有协议的动态初始化器

Posted

技术标签:

【中文标题】带有协议的动态初始化器【英文标题】:Dynamic initializer with protocol 【发布时间】:2017-04-06 07:56:13 【问题描述】:

我正在与AlamofireSwiftyJSON 合作。我想为常见情况建立通用请求和解析模型。首先,我制定了一个名为JSONConvertible 的协议。

protocol JSONConvertible 
    init?(json: JSON)

其次,我在Alamofire 中扩展Request 类。

extension Request 

    func getResult(format: [String: AnyClass]) 
        self.responseJSON  (response) in
            guard let statusCode = response.response?.statusCode else 
                return
            
            switch statusCode 
            case 200:
                var result = [String: AnyObject]()
                let json = JSON(rawValue: response.result.value!)!
                for (key, className) in format 
                    if className.self is JSONConvertible 
                        let value = className.self(json: json[key]) // get error in this line
                    
                
            case 201..<400:
                break
            case 400...Int.max:
                break
            default:
                break
            

        
       

但是我从编译器中得到一个错误。因为 AnyObject 只是协议,它没有这个初始化程序。我不想只得到字典或数组。我想获得具体类的实例。请帮我。非常感谢!

【问题讨论】:

【参考方案1】:

这是因为在 if 内部,className.self 的类型仍然是 AnyObject。您需要将其转换为JSONConvertible,然后才能使用初始化程序。

if let concreteClass = className.self as? JSONConvertible.Type 

   let value = concreteClass.init(json: json[key])

如果您熟悉 kotlin,那么在测试 if 子句中的类型时,swift 不会自动进行转换。

【讨论】:

至少没有错误了。谢谢!我会测试它是否有效。 请注意,您不需要 .selfclassName as? JSONConvertible.Type 即可。【参考方案2】:

我找到了另一种方法来解决这个问题。定义一个新协议。

protocol JSONConvertibleObject: AnyObject, JSONConvertible 


改用这个。

extension Request 

    func getResult(format: [String: JSONConvertibleObject]) 
        self.responseJSON  (response) in
            guard let statusCode = response.response?.statusCode else 
                return
            
            switch statusCode 
            case 200:
                var result = [String: AnyObject]()
                let json = JSON(rawValue: response.result.value!)!
                for (key, className) in format 
                    let value = className.self.dynamicType.init(json: json[key])
                
            case 201..<400:
                break
            case 400...Int.max:
                break
            default:
                break
            

        
       

【讨论】:

以上是关于带有协议的动态初始化器的主要内容,如果未能解决你的问题,请参考以下文章

带有可选参数的可失败的便利初始化器

UIViewController 子类的便利初始化器,带有来自 nib 的实例?

NSManagedObject 子类的 Swift 链接器错误实现具有所需初始化的协议

动态重新初始化或销毁 Bootstrap 日期选择器

为啥带有两个元素的初始化器语法将一个元素放入字符串向量而不是两个?

我可以对带有变量的向量使用 C++11 列表初始化器语法吗?