我想运行一些相互依赖的任务,因此应该按顺序执行。目前,它阻塞了我的 UI 线程,并且排序也存在一些问题。
与此相关的几个问题:
- 任务未按正确顺序执行。如果我们希望它们相继执行,需要进行哪些更改
- 代码是否在内存使用和资源消耗方面进行了优化?如何使其更加优化?
- 我们是否需要在函数调用内部使用全局队列,如下面的代码所示?
这是我的代码详细信息。我创建了一些串行队列,如下所示:
var Q0_sendDisplayName=dispatch_queue_create("Q0_sendDisplayName",DISPATCH_QUEUE_SERIAL)
var Q1_fetchFromDevice=dispatch_queue_create("fetchFromDevice",DISPATCH_QUEUE_SERIAL)
var Q2_sendPhonesToServer=dispatch_queue_create("sendPhonesToServer",DISPATCH_QUEUE_SERIAL)
我有一个想法,串行队列按顺序执行任务,因此我在串行队列上调用了我的任务。这是我的代码:
dispatch_sync(Q0_sendDisplayName,
{
self.sendNameToServer(displayName){ (result) -> () in
dispatch_sync(self.Q1_fetchFromDevice,
{
self.SyncfetchContacts({ (result) -> () in
dispatch_sync(self.Q2_sendPhonesToServer,
{ self.SyncSendPhoneNumbersToServer(self.syncPhonesList, completion: { (result) in
//.......
//....
这些函数内的代码也在全局队列上运行。不知道这是否是正确的编码方式。我已使用完成处理程序来通知该方法已完成执行。这是函数1的代码:
func sendNameToServer(var displayName:String,completion:(result:Bool)->())
{
Alamofire.request(.POST,"\(urlToSendDisplayName)",headers:header,parameters:["display_name":displayName]).responseJSON{
response in
switch response.result {
case .Success:
return completion(result: true) //......
这是函数2的代码。这个函数很长,因为它读取整个通讯录,所以我把它放在全局队列中(不知道这是否是正确的方法)。我在主队列上调用完成处理程序。这是代码:
func SyncfetchContacts(completion:(result:Bool)->())
{
let contactStore = CNContactStore()
var keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey,CNContactThumbnailImageDataKey, CNContactImageDataKey]
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
do {
try contactStore.enumerateContactsWithFetchRequest(CNContactFetchRequest(keysToFetch: keys)) { (contact, pointer) -> Void in
if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
for phoneNumber:CNLabeledValue in contact.phoneNumbers {
let a = phoneNumber.value as! CNPhoneNumber
}
}
}
dispatch_async(dispatch_get_main_queue())
{
completion(result: true)
}
}
//........
这是 function3 的代码,它内部也有一个全局队列(不知道是否正确)并在主队列上调用完成处理程序。
func SyncSendPhoneNumbersToServer(phones:[String],completion: (result:Bool)->()){
Alamofire.request(.POST,"\(url)",headers:header,parameters:["display_name":displayName]).responseJSON{
response in
switch response.result {
case .Success:
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0))
{
//enter some large data in database in a loop
dispatch_async(dispatch_get_main_queue())
{
return completion(result: true)
}
}//......
最佳答案
在 SyncfetchContacts
中,您在 contactStore.enumerateContactsWithFetchRequest
完成之前(在其完成闭包之外)调用完成处理程序。
只需将其移到那里即可:
func SyncfetchContacts(completion:(result:Bool)->()) {
...
do {
try contactStore.enumerateContactsWithFetchRequest(CNContactFetchRequest(keysToFetch: keys)) { (contact, pointer) -> Void in
if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
for phoneNumber:CNLabeledValue in contact.phoneNumbers {
let a = phoneNumber.value as! CNPhoneNumber
}
}
// here ...
dispatch_async(dispatch_get_main_queue()) {
completion(result: true)
}
}
// ... not here.
// dispatch_async(dispatch_get_main_queue()) {
// completion(result: true)
// }
}
}
关于ios - 如何在iOS中运行相互依赖的长时间运行任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41060511/