在 Xcode 9 / Swift 4 Google APIs Client Library for Objective-C for REST: threading notification not working
In Xcode 9 / Swift 4 Google APIs Client Library for Objective-C for REST: threading notification not working
在 Xcode 9 / Swift 4 中使用 Google API Client Library for Objective-C for REST:为什么 service.executeQuery return 线程线程完成前的完成通知?
我一直在尝试各种方法,但我坚持使用以下代码,其中在线程完成之前通知 returned。请参阅下面的代码、实际输出以及我希望看到的内容(线程完成后会收到通知)。
我究竟做错了什么?
谢谢
func myFunctionTest () {
let workItem = DispatchWorkItem {
self.service.executeQuery(query,
delegate: self,
didFinish: #selector(self.displayResultWithTicket2b(ticket:finishedWithObject:error:))
)
}
let group = DispatchGroup()
group.enter()
group.notify(queue: service.callbackQueue) {
print("************************** NOTIFY MAIN THREAD *************************************")
}
service.callbackQueue.async(group: group) {
workItem.perform()
}
group.leave()
}
@objc func displayResultWithTicket2b(ticket : GTLRServiceTicket,
finishedWithObject messagesResponse : GTLRGmail_ListMessagesResponse,
error : NSError?) {
//some code to run here
print("************************** 02.displayResultWithTicket2b ***************************")
}
输出
************************** 通知主线程 **************** ************************
*************************** 02.displayResultWithTicket2b ********************* ******
我所期望的 = 线程完成时会收到线程通知
*************************** 02.displayResultWithTicket2b **************** ***********
*************************** 通知主线程 ********************* *******************
问题是您正在处理异步 API 并且在完成请求提交后调用 leave
。 leave()
调用必须位于 executeQuery
调用的完成处理程序或选择器方法中。如果您要坚持使用这种基于选择器的方法,您将不得不将调度组保存在一些 属性 中,然后让 displayResultWithTicket2b
调用 leave
.
如果您使用 executeQuery
API 的基于 block/closure 完成处理程序的再现而不是基于选择器的 API,将会容易得多。然后你可以将 leave
移动到 block/closure 完成处理程序中,你就完成了。如果您使用基于块的实现,它不仅消除了在某些 属性 中保存调度组的需要,而且可能完全消除了对组的需要。
此外,回调队列可能不是为您添加自己的任务而设计的。这是一个库将用于其回调的队列(完成块 and/or 委托方法的队列将是 运行)。只需调用 executeQuery
,库就会处理 运行 在该队列上进行回调。不需要 DispatchWorkItem
:
session.executeQuery(query) { ticket, object, error in
// do whatever you need here; this runs on the callback queue
DispatchQueue.main.async {
// when you need to update model/UI, do that on the main queue
}
}
我唯一会使用调度组的情况是,如果我正在执行一系列查询并且需要知道它们何时全部完成:
let group = DispatchGroup()
for query in queries {
group.enter()
session.executeQuery(query) { ticket, object, error in
defer { group.leave() }
// do whatever you need here; this runs on the callback queue
}
}
group.notify(queue: .main) {
// do something when done; this runs on the main queue
}
在 Xcode 9 / Swift 4 中使用 Google API Client Library for Objective-C for REST:为什么 service.executeQuery return 线程线程完成前的完成通知? 我一直在尝试各种方法,但我坚持使用以下代码,其中在线程完成之前通知 returned。请参阅下面的代码、实际输出以及我希望看到的内容(线程完成后会收到通知)。 我究竟做错了什么? 谢谢
func myFunctionTest () {
let workItem = DispatchWorkItem {
self.service.executeQuery(query,
delegate: self,
didFinish: #selector(self.displayResultWithTicket2b(ticket:finishedWithObject:error:))
)
}
let group = DispatchGroup()
group.enter()
group.notify(queue: service.callbackQueue) {
print("************************** NOTIFY MAIN THREAD *************************************")
}
service.callbackQueue.async(group: group) {
workItem.perform()
}
group.leave()
}
@objc func displayResultWithTicket2b(ticket : GTLRServiceTicket,
finishedWithObject messagesResponse : GTLRGmail_ListMessagesResponse,
error : NSError?) {
//some code to run here
print("************************** 02.displayResultWithTicket2b ***************************")
}
输出
************************** 通知主线程 **************** ************************ *************************** 02.displayResultWithTicket2b ********************* ******
我所期望的 = 线程完成时会收到线程通知
*************************** 02.displayResultWithTicket2b **************** *********** *************************** 通知主线程 ********************* *******************
问题是您正在处理异步 API 并且在完成请求提交后调用 leave
。 leave()
调用必须位于 executeQuery
调用的完成处理程序或选择器方法中。如果您要坚持使用这种基于选择器的方法,您将不得不将调度组保存在一些 属性 中,然后让 displayResultWithTicket2b
调用 leave
.
如果您使用 executeQuery
API 的基于 block/closure 完成处理程序的再现而不是基于选择器的 API,将会容易得多。然后你可以将 leave
移动到 block/closure 完成处理程序中,你就完成了。如果您使用基于块的实现,它不仅消除了在某些 属性 中保存调度组的需要,而且可能完全消除了对组的需要。
此外,回调队列可能不是为您添加自己的任务而设计的。这是一个库将用于其回调的队列(完成块 and/or 委托方法的队列将是 运行)。只需调用 executeQuery
,库就会处理 运行 在该队列上进行回调。不需要 DispatchWorkItem
:
session.executeQuery(query) { ticket, object, error in
// do whatever you need here; this runs on the callback queue
DispatchQueue.main.async {
// when you need to update model/UI, do that on the main queue
}
}
我唯一会使用调度组的情况是,如果我正在执行一系列查询并且需要知道它们何时全部完成:
let group = DispatchGroup()
for query in queries {
group.enter()
session.executeQuery(query) { ticket, object, error in
defer { group.leave() }
// do whatever you need here; this runs on the callback queue
}
}
group.notify(queue: .main) {
// do something when done; this runs on the main queue
}