Swift中类中的KVO可观察属性位置

时间:2018-10-08 03:58:16

标签: swift

我正在阅读一本雷·温德利希(Ray Wenderlich)的书,有一次它提到将可观察的属性标记为需要动态分配,例如:

  @objc dynamic private(set) var sources: [Source] = []
  @objc dynamic private(set) var articles: [Article] = []

现在,我自然会将它们放在相关课程的顶部。但是,该示例使它们进一步下降,如下所示。这样做的理由是什么?

import Foundation

class NewsAPI: NSObject {

  static let service = NewsAPI()

  private struct Response: Codable {
    let sources: [Source]?
    let articles: [Article]?
  }

  private enum API {
    private static let basePath = "https://newsapi.org/v1"
    /*
     Head on over to https://newsapi.org/register to get your
     free API key, and then replace the value below with it.
     */
    private static let key = "00000000000000000000000000000000"

    case sources
    case articles(Source)

    func fetch(completion: @escaping (Data) -> ()) {
      let session = URLSession(configuration: .default)
      let task = session.dataTask(with: path()) { (data, response, error) in
        guard let data = data, error == nil else { return }
        completion(data)
      }
      task.resume()
    }

    private func path() -> URL {
      switch self {
      case .sources:
        return URL(string: "\(API.basePath)/sources")!
      case .articles(let source):
        return URL(string: "\(API.basePath)/articles?source=\(source.id)&apiKey=\(API.key)")!
      }
    }
  }

  @objc dynamic private(set) var sources: [Source] = []
  @objc dynamic private(set) var articles: [Article] = []

  func fetchSources() {
    API.sources.fetch { data in
      if let sources = try! JSONDecoder().decode(Response.self, from: data).sources {
        self.sources = sources
      }
    }
  }

  func fetchArticles(for source: Source) {
    let formatter = ISO8601DateFormatter()
    let customDateHandler: (Decoder) throws -> Date = { decoder in
      var string = try decoder.singleValueContainer().decode(String.self)
      string.deleteMillisecondsIfPresent()
      guard let date = formatter.date(from: string) else { return Date() }
      return date
    }
    API.articles(source).fetch { data in
      let decoder = JSONDecoder()
      decoder.dateDecodingStrategy = .custom(customDateHandler)
      if let articles = try! decoder.decode(Response.self, from: data).articles {
        self.articles = articles
      }
    }
  }

  func resetArticles() {
    articles = []
  }
}

1 个答案:

答案 0 :(得分:2)

  

这样做的理由是什么?

没有“理性”。您将他们置于首位的是什么?你为什么说“自然”?方法和属性可以按任何顺序排列。没有法律说财产必须先行。我个人喜欢尽可能地将属性与最常使用它们的函数放在一起。也许该代码的作者也这样做。纯粹是出于口味问题。