Присвойте значение, полученное от @escaping, переменной экземпляра в другом классе в swift - PullRequest
0 голосов
/ 19 сентября 2018

Я считаю, что я неправильно понял некоторую концепцию в Swift и могу присвоить полученный массив моей переменной экземпляра.Может кто-нибудь объяснить, почему мой массив announcementsList содержит 0 элементов?

UIViewController.swift

var announcementsList: [Announcement] = []

override func viewDidLoad() {
   super.viewDidLoad()
   api.getAnnouncements(){ announcements in  //<- announcements is array which has 12 elements
       for ann in announcements{
          self.announcementsList.append(ann)
       }
   }
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return announcementsList.count   //<- have 0 here
}

API.swift

func getAnnouncements(completion:  @escaping ([Announcement]) -> ()){
    var announcements: [Announcement] = []
    let url = URL(string: "https://api.ca/announcements")!

    let task = self.session.dataTask(with: url) {
        data, response, error in
        if let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
            guard let announcements_json = json!["announcements"] as? [[String: Any]]
                else { return }

            for announcement in announcements_json{
                let title = announcement["title"] as! String
                let desc = announcement["description"] as! String
                announcements.append(Announcement(title: title,desc: desc))
            }

        }
        completion(announcements)
    }
    task.resume()
}

PS: в мою защиту я должен сказать, что код работает на Java очень хорошо

UPD

In UIViewController.swift если заглянуть внутрь моего announcementsList в viewWillDisappear(), я получу свои объекты там.Поэтому я предполагаю, что tableView() начал считать элементы раньше, чем они стали переназначаться в viewDidLoad().

Теперь вопрос, как назначить объекты внутри viewDidLoad() новому массиву быстрее, чем tableView(), начните считать их.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018
var announcementsList: [Announcement] = [] {
    didSet {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}

override func viewDidLoad() {
   super.viewDidLoad()
   api.getAnnouncements { announcements in
      self.announcementsList = announcements
   }
}
0 голосов
/ 19 сентября 2018

Операция асинхронная, поэтому tableView перезагружается, когда появляется VC, и в этот момент ответ еще не возвращается

for ann in announcements{
   self.announcementsList.append(ann)
}
self.tableView.reloadData()

Кстати, почему бы не

self.announcementsList = announcements
self.tableView.reloadData()

Также неНе знаю текущую тему обратного вызова, так что

DispatchQueue.main.async {
   self.announcementsList = announcements
   self.tableView.reloadData()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...