【发布时间】:2018-07-01 03:07:00
【问题描述】:
我不熟悉 swift 并使用异步代码。
我有一个从 API 获取数据、将数据放入对象并将这些对象放入数组的方法。然后我想用数组中这些对象的数据更新 UI。
为了说明 UI 得到更新,我将更改标签的值。
因为从 API 中获取信息的方法是异步的,所以我无法从中返回值。相反,我传递了一个回调:
@IBOutlet var labelTest: UILabel!
private var eventsArray : Array<Event> = Array<Event>()
override func viewDidLoad() {
APIAccessUtil.getEventsFromAPI({(eventsList: Array<Event>) -> Void in
self.eventsArray = eventsList
})
sleep(5) //this is of course not good, but I'll leave it here to illustrate what's going on.
self.labelTest.text = eventsArray[0].description
}
这有效,因为让线程休眠会留出时间让数组被填满。但是,让主线程休眠是一个非常糟糕的主意,并且不能保证此时会返回数据。
如果sleep(...) 被删除,则在getEventsFromAPI 调用完成之前尝试更新 UI 标签,从而产生运行时错误(因为数组仍将为 nil)。
尝试 2:
@IBOutlet var labelTest: UILabel!
private var eventsArray : Array<Event> = Array<Event>()
override func viewDidLoad() {
APIAccessUtil.getEventsFromAPI({(eventsList: Array<Event>) -> Void in
self.eventsArray = eventsList
self.labelTest.text = eventsArray[0].description
})
}
在尝试 #2 中,我正在从后台线程更新 UI,这并不好并产生以下警告:
此应用程序正在从后台线程修改自动布局引擎,这可能会导致引擎损坏和奇怪的崩溃。这将在未来的版本中导致异常。
那么,在getEventsFromAPI 调用完成后,有什么方法可以从主线程更新 UI(即更改标签文本)(这样数组实例变量现在不为零)?
【问题讨论】:
标签: ios swift asynchronous ios9