SwiftJSON源码学习小结

其实SwiftJSON源码一共加起来也就不到1500行,我翻来覆去的看了几次,其实很多地方都是看得不是特别明白.这里只是将自己觉得可以加以利用的地方列出来.

CustomNSError协议的使用

其实这个协议是继承自协议Error的,需要注意的是这个协议CustomNSError更有利于将Error向NSError进行as使用.
SwiftJSON的源码如下

public enum SwiftyJSONError: Int, Swift.Error {
    case unsupportedType = 999
    case indexOutOfBounds = 900
    case elementTooDeep = 902
    case wrongType = 901
    case notExist = 500
    case invalidJSON = 490
}

extension SwiftyJSONError: CustomNSError {

    /// return the error domain of SwiftyJSONError
    public static var errorDomain: String { return "com.swiftyjson.SwiftyJSON" }

    /// return the error code of SwiftyJSONError
    public var errorCode: Int { return self.rawValue }

    /// return the userInfo of SwiftyJSONError
    public var errorUserInfo: [String: Any] {
        switch self {
        case .unsupportedType:
            return [NSLocalizedDescriptionKey: "It is an unsupported type."]
        case .indexOutOfBounds:
            return [NSLocalizedDescriptionKey: "Array Index is out of bounds."]
        case .wrongType:
            return [NSLocalizedDescriptionKey: "Couldn't merge, because the JSONs differ in type on top level."]
        case .notExist:
            return [NSLocalizedDescriptionKey: "Dictionary key does not exist."]
        case .invalidJSON:
            return [NSLocalizedDescriptionKey: "JSON is invalid."]
        case .elementTooDeep:
            return [NSLocalizedDescriptionKey: "Element too deep. Increase maxObjectDepth and make sure there is no reference loop."]
        }
    }
}

值得注意的是,这个枚举必须要定义类型,而且最好是Int类型.因为遵守CustomNSError协议,必须返回errorCode这个属性, 这个时候一般都是用枚举的rawValue,枚举定义为Int,那么就可以进行无缝的使用

通过switch 来替换 as用法

一般当有个对象我们需要转换类型的使用我一般是这么使用的

func toNSURL(url: Any) -> NSURL? {
    if url is NSURL {
        return url as? NSURL
    }
    
    if url is URL {
        return (url as! URL) as NSURL
    }
    
    if url is String {
        return NSURL(string: (url as! String))
    }
    
    return nil
}

其实这个完全是可以通过switch来进行处理

func asNSURL(any: Any) -> NSURL? {
    switch any {
    case let nsURL as NSURL:
        return nsURL
    case let url as URL:
        return url as NSURL
    case let string as String:
        return NSURL(string: string)
    default:
        return nil
    }
}

少一些解包少一些感叹号,少一些烦恼

源码出处,其中这里面还包含了在map函数的递归调用,并且SwiftJSON中多处这样进行了使用:

private func unwrap(_ object: Any) -> Any {
    switch object {
    case let json as JSON:
        return unwrap(json.object)
    case let array as [Any]:
        return array.map(unwrap)
    case let dictionary as [String: Any]:
        var unwrappedDic = dictionary
        for (k, v) in dictionary {
            unwrappedDic[k] = unwrap(v)
        }
        return unwrappedDic
    default:
        return object
    }
}

NSNumber的比较处理

这个源码处理的比较详细,完全可以copy一份在自己的分类中使用,因为这个分类在SwiftJSON是对内,所以基本上不用担心copy一份引起冲突

private let trueNumber = NSNumber(value: true)
private let falseNumber = NSNumber(value: false)
private let trueObjCType = String(cString: trueNumber.objCType)
private let falseObjCType = String(cString: falseNumber.objCType)

// MARK: - NSNumber: Comparable

extension NSNumber {
    fileprivate var isBool: Bool {
        let objCType = String(cString: self.objCType)
        if (self.compare(trueNumber) == .orderedSame && objCType == trueObjCType) || (self.compare(falseNumber) == .orderedSame && objCType == falseObjCType) {
            return true
        } else {
            return false
        }
    }
}

func == (lhs: NSNumber, rhs: NSNumber) -> Bool {
    switch (lhs.isBool, rhs.isBool) {
    case (false, true):
        return false
    case (true, false):
        return false
    default:
        return lhs.compare(rhs) == .orderedSame
    }
}

func != (lhs: NSNumber, rhs: NSNumber) -> Bool {
    return !(lhs == rhs)
}

func < (lhs: NSNumber, rhs: NSNumber) -> Bool {

    switch (lhs.isBool, rhs.isBool) {
    case (false, true):
        return false
    case (true, false):
        return false
    default:
        return lhs.compare(rhs) == .orderedAscending
    }
}

func > (lhs: NSNumber, rhs: NSNumber) -> Bool {

    switch (lhs.isBool, rhs.isBool) {
    case (false, true):
        return false
    case (true, false):
        return false
    default:
        return lhs.compare(rhs) == ComparisonResult.orderedDescending
    }
}

func <= (lhs: NSNumber, rhs: NSNumber) -> Bool {

    switch (lhs.isBool, rhs.isBool) {
    case (false, true):
        return false
    case (true, false):
        return false
    default:
        return lhs.compare(rhs) != .orderedDescending
    }
}

func >= (lhs: NSNumber, rhs: NSNumber) -> Bool {

    switch (lhs.isBool, rhs.isBool) {
    case (false, true):
        return false
    case (true, false):
        return false
    default:
        return lhs.compare(rhs) != .orderedAscending
    }
}

转载于:https://www.jianshu.com/p/06f559f9e518

猜你喜欢

转载自blog.csdn.net/weixin_34375233/article/details/91270572