ios - 如何在iOS中运行相互依赖的长时间运行任务

标签 ios swift xcode multithreading queue

我想运行一些相互依赖的任务,因此应该按顺序执行。目前,它阻塞了我的 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/

相关文章:

objective-c - 无法在 iOS 后台模式下重新启动中断的音频输入队列

ios - 在 Swift 中设置自定义 segue 方式(从顶部到按钮的方向)

ios - popOver 不跟随 slider -iOS/Xcode

ios - 将 Unicode 表情符号转换为 NSString (Not\ue415 格式)

iphone - uitableView,带标签的新 View

iphone - 在ios中将html转换为图像

ios - 收藏 View : UIViewRepresentable + NavigationView

json - 将多个变量保存到 NSUserdefaults 并按保存顺序显示在另一个 View Controller 上的最佳方法是什么?

ios - 在 XCode 5 中查看类/协议(protocol)层次结构

objective-c - Cocoa - 在运行时确定类的属性