Firebase 将在闭包中运行,因此在另一个线程中运行。当 Firebase 完成加载数据时,我尝试调用完成处理程序。
但是我运行它时出错。 “Thread 1: EXC_BAD_ACCESS(Code=EXC_1386_GPFLT)” 我知道问题出在错误的线程上,但不知道如何解决。我正在尝试编辑 View Controller 上组件的状态。请帮忙
func refreshData(completionHandler:@escaping (Bool)->() ) {
//I ignore some unrelated statements here
//....
//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 taskItem = Task(snapshot: item as! DataSnapshot)
newItems.append(taskItem!)
}
let merged = drafts + newItems
self.items = merged
self.tableView.reloadData()
completionHandler(true) //The line causes error
})
}
我在 viewDidLoad 中调用了这个函数。
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()
}
}
更新崩溃日志:
> * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x111606db0)
> frame #0: 0x0000000111606db0 CoreFoundation`__NSSingleObjectArrayI
> frame #1: 0x000000010f61248a MGSupport`thunk at TaskTableViewController.swift:0 * frame #2: 0x000000010f612294
> MGSupport`TaskTableViewController.(self=0x00007fa6ead25860,
> completionHandler=0x000000010f6124e0 MGSupport`partial apply forwarder
> for reabstraction thunk helper from @callee_unowned @convention(block)
> (@unowned ObjectiveC.ObjCBool) -> () to @callee_owned (@unowned
> Swift.Bool) -> () at TaskTableViewController.swift) -> ()) ->
> ()).(closure #1).(closure #1) at TaskTableViewController.swift:95
> frame #3: 0x000000010f6122d7 MGSupport`thunk at TaskTableViewController.swift:0
> frame #4: 0x00000001140c94a6 libdispatch.dylib`_dispatch_call_block_and_release + 12
> frame #5: 0x00000001140f205c libdispatch.dylib`_dispatch_client_callout + 8
> frame #6: 0x00000001140d340b libdispatch.dylib`_dispatch_main_queue_callback_4CF + 411
> frame #7: 0x0000000111311909 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
> frame #8: 0x00000001112d7ae4 CoreFoundation`__CFRunLoopRun + 2164
> frame #9: 0x00000001112d7016 CoreFoundation`CFRunLoopRunSpecific + 406
> frame #10: 0x000000011548ea24 GraphicsServices`GSEventRunModal + 62
> frame #11: 0x0000000111e59134 UIKit`UIApplicationMain + 159
> frame #12: 0x000000010f62c687 MGSupport`main at AppDelegate.swift:14
> frame #13: 0x000000011413e65d libdyld.dylib`start + 1
调试更新: 我尝试设置断点,我发现只有第一次从 viewDidLoad() 调用函数时才能成功调用 completionHandler。但是如果用户向下滚动屏幕并通过 refreshControl 的自动调用再次调用 refreshData 函数,则它无法再访问 completionHandler。有什么想法吗?
最佳答案
这是因为 refreshControl
选择器。选择器没有任何完成处理程序,当 refreshControl
值更改时,完成 block 正在尝试执行,但没有用于刷新控制的完成 block 。
所以最好为你的 refreshData(_:)
提供默认的完成 block
func refreshData(completionHandler:@escaping (Bool)->() = { _ in }) {
//You code is here.
}
关于ios - Firebase调用回调函数后如何回到main_thread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45206808/