发现意外之美 - SwiftyJSON 源码学习(2) | 咖啡时间

swift 发布于 2017年11月20日

我们在上篇文章中分析过了 SwiftyJSON 中 JSON 类的构造方法。如果没有看过前一篇,建议大家先把前一篇的内容做一个了解,可以参看这里: http://swiftcafe.io/2015/10/27/cafe-time-swifty-json/

继续启程

做好准备后,咱们就开始启程吧~

咱们分析完了 JSON 结构体的几个构造方法,接下来看看 JSON 结构体的属性定义吧。首先我们想到的属性,应该就是 self.object 了,这个属性咱们在前面的构造方法分析中见到了很多次。它用来存储 `JSON 结构体内部的,前面我们已经了解过了。那么我们想象它的定义会是什么样的?

可能会觉得是这样的:

public struct JSON {

  //...

  public var object: AnyObject

  //...
}

但实际上它是这样的:


public struct JSON {

  //...

  public var object: AnyObject {
    get {
        switch self.type {
        case .Array:
            return self.rawArray
        case .Dictionary:
            return self.rawDictionary
        case .String:
            return self.rawString
        case .Number:
            return self.rawNumber
        case .Bool:
            return self.rawNumber
        default:
            return self.rawNull
        }
    }
    set {
        _error = nil
        switch newValue {
        case let number as NSNumber:
            if number.isBool {
                _type = .Bool
            } else {
                _type = .Number
            }
            self.rawNumber = number
        case  let string as String:
            _type = .String
            self.rawString = string
        case  _ as NSNull:
            _type = .Null
        case let array as [AnyObject]:
            _type = .Array
            self.rawArray = array
        case let dictionary as [String : AnyObject]:
            _type = .Dictionary
            self.rawDictionary = dictionary
        default:
            _type = .Unknown
            _error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"])
        }
    }

  //...
}

嗯,比想象中复杂很多是吧。没关系,我们来一一击破。

首先,Swift 中我们可以这样定义属性:

public var object: AnyObject

当然,我们还可以自定义属性的 getter 和 setter:

public var object: AnyObject {

  get {

  }

  set {

  }

}

JSON 对象的 object 属性,就是这样的自定义属性,我们先来看它的 getter:

get {
    switch self.type {
    case .Array:
        return self.rawArray
    case .Dictionary:
        return self.rawDictionary
    case .String:
        return self.rawString
    case .Number:
        return self.rawNumber
    case .Bool:
        return self.rawNumber
    default:
        return self.rawNull
    }
}

getter 方法里面用到了另外一个属性 - self.type, 我们先来看看它的定义吧:

public var type: Type { get { return _type } }

这个属性只定义了 getter 方法,类型是 Type 并且 getter 方法返回的是一个内部私有变量 _type

Type 的定义如下:

public enum Type :Int{

    case Number
    case String
    case Bool
    case Array
    case Dictionary
    case Null
    case Unknown
}

看到了,Type 实际上定义的是 JSON 所包含的所有数据类型,也就是说,self.object 属性的 getter 方法,会根据当前 object 的类型,返回相应的输出值。那么同理, setter 方法也是一样的原理:

set {
    _error = nil
    switch newValue {
    case let number as NSNumber:
        if number.isBool {
            _type = .Bool
        } else {
            _type = .Number
        }
        self.rawNumber = number
    case  let string as String:
        _type = .String
        self.rawString = string
    case  _ as NSNull:
        _type = .Null
    case let array as [AnyObject]:
        _type = .Array
        self.rawArray = array
    case let dictionary as [String : AnyObject]:
        _type = .Dictionary
        self.rawDictionary = dictionary
    default:
        _type = .Unknown
        _error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"])
    }
}

很明显了吧,newValue 是 Swift 中的特殊值,它表示的是 setter 方法传递进来的新的要设置的值,这里的 swich 语句,正是对这个新的值进行了类型判断,这个判断方式是使用了 case let number as NSNumber 这种方式,整个代码结构非常清晰。

根据 newValue 的实际类型,将 _type 变量设置好。然后设置相应的 rawXXX 值。

一目了然, object 属性,不是单单的存储值,还会区分值得类型。

JSON 结构体的主要结构怎么就都分析完了,这个结构体里面还定义了一些其他的属性,咱们也来看一看。

几个私有变量:

private var rawArray: [AnyObject] = []
private var rawDictionary: [String : AnyObject] = [:]
private var rawString: String = ""
private var rawNumber: NSNumber = 0
private var rawNull: NSNull = NSNull()
/// Private type
private var _type: Type = .Null
/// prviate error
private var _error: NSError? = nil

其中名称为 rawXXX 的变量代表 object 的各个数据类型分别表示的底层存储。 _type 变量代表 object 属性中存储的数据类型。 _error 变量用来错放一些错误信息。

最后,剩余的几个属性定义:

/// json type
public var type: Type { get { return _type } }

/// Error in JSON
public var error: NSError? { get { return self._error } }

/// The static null json
@available(*, unavailable, renamed="null")
public static var nullJSON: JSON { get { return null } }
public static var null: JSON { get { return JSON(NSNull()) } }

其中,typeerror 分别包装了同名的私有方法。最后几行,的两个静态属性,用于表示 jSON 中得空值,其他地方会用到。

结语

到这里,JSON 结构体的基础定义咱们就都分析完了。好像也不是太多哦。通过这一系列分析,我们得知,JSON 结构体的 object 属性并没有直接存储数据,而是会根据传入的数据的类型,来存放到相应的 rawXXX 变量中。

那么,咱们对 Swifty JSON 的学习就到此结束了么? 当然没有,Swifty JSON 中还用到了 extension 机制,也就是说 JSON 类的初步定义只是一个开始,Swifty JSON 还对 JSON 类进行了 extension 处理。关于这些内容,就让我们下次继续道来吧。


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩
swift-cafe