2016-12-09 3 views
0

Я хочу запускать некоторые задачи, которые зависят друг от друга, поэтому их следует выполнять в порядке. В настоящее время он блокирует мой поток пользовательского интерфейса, а также вызывает некоторые проблемы при заказе.Как выполнять бегущие задачи в iOS, которые зависят друг от друга

Пара вопросов относительно этого:

  • Задачи не выполняются в правильном порядке. Что нужно сделать, если мы хотим, чтобы они выполнялись один за другим
  • Является ли код оптимизированным с точки зрения использования памяти и потребления ресурсов? Как его можно сделать более оптимизированным?
  • Нужны ли нам глобальные очереди внутри вызова функции также, как показано в коде ниже?

Вот мои данные кодов. Я создал несколько последовательных очередей следующим образом:

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) 
       } 


      }//...... 
+0

Поскольку задачи все имеют завершающие блоки, нет необходимости для dispatch_sync вызовов. Вы можете использовать группу отправки, если вы хотите выполнить какое-то окончательное действие после завершения всей работы. – Paulw11

+0

Спасибо. нам нужны функции 'dispatch_sync' внутри? – Sumaira

ответ

0

В 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) 
//   } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^