美文网首页
[Swift] 让ObjectMapper支持Contiguou

[Swift] 让ObjectMapper支持Contiguou

作者: 无衔 | 来源:发表于2018-08-04 20:35 被阅读39次

看下ObjectMapper源码可以确定它原本是不支持的ContiguousArray。
因为性能问题如果选择了ContiguousArray,那么你大概需要做的大概就是下面两个动作

1.完善操作符<-重载

首先是关键的mapping方法

public mutating func mapping(map: Map)

它需要用到的<-操作符,我们需要增加一个重载来处理ContiguousArray的逻辑
代码如下

public func <- <T: BaseMappable>(left: inout ContiguousArray<T>, right: Map) {
    var altArray = [T]()
    switch right.mappingType {
    case .fromJSON where right.isKeyPresent:
        FromJSON.objectArray(&altArray, map: right)
        for item in altArray {
            left.append(item)
        }
    case .toJSON:
        for item in left {
            altArray.append(item)
        }
        altArray >>> right
    default: ()
    }
}

这个重载写得比较偷懒。只是借助ObjectMapper对Array的实现做跳板。

2.补充BaseMappable 对ContiguousArray 的扩展

let str = result.toJSONString()

如果要支持以上功能,要增加toJSON的代码。这里做一个扩展,通过Array的实现作为跳板,直接上代码。

public extension ContiguousArray where Element: BaseMappable {
    
    /// Initialize Array from a JSON String
    public init?(JSONString: String, context: MapContext? = nil) {
        if let obj: [Element] = Mapper(context: context).mapArray(JSONString: JSONString) {
            self = ContiguousArray<Element>()
            for item in obj {
                self.append(item)
            }
        } else {
            return nil
        }
    }
    
    /// Initialize Array from a JSON Array
    public init(JSONArray: [[String: Any]], context: MapContext? = nil) {
        let obj: [Element] = Mapper(context: context).mapArray(JSONArray: JSONArray)
        self = ContiguousArray<Element>()
        for item in obj {
            self.append(item)
        }
    }
    
    /// Returns the JSON Array
    public func toJSON() -> [[String: Any]] {
        return Mapper().toJSONArray(convert(input:self))
    }
    
    /// Returns the JSON String for the object
    public func toJSONString(prettyPrint: Bool = false) -> String? {
        return Mapper().toJSONString(convert(input:self), prettyPrint: prettyPrint)
    }
    
    private func convert(input:ContiguousArray<Element>) -> [Element]{
        var resultArray = [Element]()
        for item in input {
            resultArray.append(item)
        }
        return resultArray
    }
    
    private func convert(input:[Element]) -> ContiguousArray<Element> {
        var resultArray = ContiguousArray<Element>()
        for item in input {
            resultArray.append(item)
        }
        return resultArray
    }
}

这样快速解决问题。笔者是用JSON来存储测试数据源和测试结果的。所以对这性能无要求。如果是正式使用,建议还是完整实现。摒弃从Array到ContiguousArray进行数据来回复制的过程。

相关文章

网友评论

      本文标题:[Swift] 让ObjectMapper支持Contiguou

      本文链接:https://www.haomeiwen.com/subject/ooomvftx.html