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


这篇为 SwiftyJSON 源码学习第二篇。在上一篇中我们分析了 SwiftyJSON 的构造方法,从中理清了它的基本结构。在这篇中,我们将继续之前的探索,一起发现意外之美。

我们在上篇文章中分析过了 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

你可能感兴趣的:(发现意外之美 - SwiftyJSON 源码学习(2) | 咖啡时间)