MainViewController 没有收到来自 NSNotificationCenter 的通知

MainViewController doesn't get notifications from NSNotificationCenter

我的主要 class 是一个 UITableViewController。 我正在使用 ConnectionManager class 获取一些 JSON 数据并使用 ItemManager class 解析它。 classes 之间的通信是使用 NotificationCenter 完成的。每当有来自 ConnectionManager 的响应时,它都会向 ItemManager 发送通知,然后对其进行解析。

ConnectionManager 发布通知并且 ItemManager 正确接收它们。我想使用相同的方法来更新我的 table 视图。问题出在我的主 class 上。解析完成后,它不会收到来自 ItemManager 的通知。

一些代码:

class ConnectionManager {

  private let URL = "http://foo.json"
  private var response: Data?

  init () {
    getData()
  }

  func getData() {
    let req = NSMutableURLRequest(url: NSURL(string: URL)! as URL)
    req.httpMethod = "GET"
    URLSession.shared.dataTask(with: req as URLRequest) { data, response, error in
      if error != nil {
        //HTTP request failed
        NSLog(error?.localizedDescription ?? "Unknown Error")
        NotificationCenter.default.post(name: Notification.Name(NotificationCenterKeys.NOK), object: nil)
      } else {
        //HTTP request succeeded
        self.response = data
        NotificationCenter.default.post(name: Notification.Name(NotificationCenterKeys.OK), object: nil)
      }
      }.resume()
  }
}

class ItemManager {
  private var cm: ConnectionManager
  private var items = [Item]()

  init() {
    self.cm = ConnectionManager()
    NotificationCenter.default.addObserver(self, selector: #selector(self.parseResponse), name: Notification.Name(NotificationCenterKeys.OK), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.noData), name: Notification.Name(NotificationCenterKeys.NOK), object: nil)
  }

  @objc private func noData() {
    NSLog("No data to parse")
  }

  @objc private func parseResponse() {
    do {
      if let data = cm.getResponse() {
        let items: NSDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
        let rawItems = items["numbers"] as! [Int]
        self.items = parseItems(rawItems: rawItems)
    NotificationCenter.default.post(name: Notification.Name(NotificationCenterKeys.PARSED), object: nil)

      }
    } catch {
      print("Error deserializing JSON: \(error)")
    }
  }

最后是我的 UITableViewController:

class MainViewTableViewController: UITableViewController {

  var items = [Item]()
  var dataAvailable = false
  var im = ItemManager()
  var dataLabel = "Loading Data..."

  override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(self.updateTable), name: Notification.Name(NotificationCenterKeys.PARSED), object: nil)
    setTable()
  }

  @objc func updateTable() {
    if im.getItems()?.count != 0 {
      items = im.getItems()!
      dataAvailable = true
    } else {
      dataAvailable = false
      dataLabel = "No Data Available"
    }
    self.tableView.reloadData()
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
  }

  func setTable() {
    title = "Test"
    tableView.rowHeight = 40
  }

  // MARK: - Table view data source

  override func numberOfSections(in tableView: UITableView) -> Int {
    var numOfSections = 0
    if dataAvailable {
      numOfSections = 4
      return numOfSections
    } else {
      let noDataLabel: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
      noDataLabel.text = dataLabel
      noDataLabel.textColor = UIColor.black
      noDataLabel.textAlignment = .center
      tableView.backgroundView = noDataLabel
      tableView.separatorStyle = .none
    }
    return numOfSections
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return getNumOfItemsPerSection(section: section)
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
    guard let sectionNumber = SectionNumber(rawValue: indexPath.section) else { return cell }
    let elements = self.items.filter({ [=11=].sectionNumber == sectionNumber })
    cell.nameLabel?.text = elements[indexPath.row].itemNumber?.description
    if elements[indexPath.row].checkmark {
      cell.accessoryType = .checkmark
    } else { cell.accessoryType = .none }
    return cell
  }

  func getNumOfItemsPerSection(section: Int) -> Int {
    guard let sectionNumber = SectionNumber(rawValue: section) else { return 0 }
    return self.items.filter({ [=11=].sectionNumber == sectionNumber }).count
  }

  override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "Section \(section + 1)"
  }
}

找到问题了! 收到通知后注册观察员(ups)

class MainViewTableViewController: UITableViewController {

  var items = [Item]()
  var dataAvailable = false
  var im: ItemManager? = nil

  override func viewDidLoad() {
    super.viewDidLoad()
    setTable()
    NotificationCenter.default.addObserver(self, selector: #selector(self.updateTable),
                                           name: Notification.Name(NotificationCenterKeys.END), object: nil)
    im = ItemManager()
  }

...

现在工作正常:-)