【发布时间】:2017-07-20 02:32:10
【问题描述】:
我使用 Firebase 作为我的数据结构。我在 UITableView 的 refreshControl 中使用完成处理程序,以便在完成从 Firebase 加载所有数据时停止刷新。
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl = UIRefreshControl()
self.refreshControl!.addTarget(self, action: #selector(refreshData),for: .valueChanged)
self.refreshControl!.attributedTitle = NSAttributedString(string: "Update the data")
refreshData{ _ in
self.refreshControl!.endRefreshing()
}
}
这是我的 refreshData 方法
func refreshData(completionHandler:@escaping (Bool)->() ) {
//Remove old data
self.items.removeAll()
//Renew all data
var ref: DatabaseReference!
ref = Database.database().reference(withPath: "tasks")
//Loading local drafts
var drafts : [Task]!
if let local_drafts = NSKeyedUnarchiver.unarchiveObject(withFile: Task.ArchiveURL.path) as? [Task] {
drafts = local_drafts
}
else{
drafts = []
}
//Reloading the database
ref.observe(.value, with: { snapshot in
var newItems: [Task] = []
self.num_of_tasks = Int(snapshot.childrenCount)
for item in snapshot.children {
//let local = item as! DataSnapshot
//let snapshotValue = local.value as! [String: AnyObject]
//print(snapshotValue["main_content"] as! String!)
let taskItem = Task(snapshot: item as! DataSnapshot)
newItems.append(taskItem!)
}
let merged = drafts + newItems
self.items = merged
completionHandler(true) //THIS LINE HAS ERR_BAD_ACCESS
})
}
我认为问题可能是viewDidLoad中的两个refreshData。但我不知道如何解决它。如何添加带有处理程序的 refreshData 作为选择器?
【问题讨论】:
-
您是否知道您何时开启与关闭主 (UI) 线程?任何时候你进入一个闭包,确保你在你需要的线程中——要操作一个 UI 控件,你必须在 UI 线程上,我怀疑你没有费心去安排它。
-
@BaseZen 对不起,我不太明白你的意思。我将completionHandler中的refresherControl注释掉并添加打印语句,我仍然得到这个错误。
-
如果您不了解线程上下文和 UI 操作的基本规则:它必须在主 UI 线程上 - 这就是问题所在。看看 iOS 中这些主题的背景阅读是否有帮助。
-
@BaseZen 所以闭包里面的代码不在UI线程中,但是我尝试在ui线程中使用handler?如果这是问题,如何解决?将代码包装在一些 dispatchQueue 中?
标签: ios swift uitableview swift3 uirefreshcontrol