Firebaseはクロージャで実行されるため、別のスレッドで実行されます。 Firebaseがデータの読み込みを終了したら、私は補完ハンドラを呼び出そうとします。Firebaseがコールバック関数を呼び出した後にmain_threadに戻る方法は?
しかし、私はそれを実行するエラーがあります。 "スレッド1:EXC_BAD_ACCESS(コード= EXC_1386_GPFLT)"私は間違ったスレッドに関する問題を知っていますが、それを修正する方法はわかりません。私は、ビューコントローラ上のコンポーネントの状態を編集しようとしています。助けてください
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()
}
}
更新:UDPATE
> * 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にアクセスできなくなります。何か案が?
は、あなたの質問とクラッシュログを追加するためのデフォルトの補完ブロックを与える... – Subramanian
は、私はすでにクラッシュログを添付main.asyncブロックコール – Joshua
@SubramanianにreloadDataとcompletionHandlerを置きます。ありがとう – Chen