2016-12-09 15 views
0

お互いに依存するいくつかのタスクを実行したいので、順番に実行する必要があります。現在のところ、私のUIスレッドをブロックし、また注文に問題があります。このに関する質問のお互いに依存している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 



               //....... 
               //.... 

これらの関数内のコードもグローバルキューで実行されています。それが正しいコード方法であるかどうかは分かりません。私は完了ハンドラを使用してメソッドが実行を完了したことを通知しました。 function1のコードは次のとおりです。

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) //...... 

ここにfunction2のコードがあります。この関数は、全体の連絡先の本を読んでいるので、私はそれが正しい方法であるかどうかわからないグローバルキュー内に配置したとして長いです。メインキューの補完ハンドラを呼び出します。ここでは、コードは次のとおりです。

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

ここで再び内部グローバルキューを持っている(その右の場合は知らない)とメインキューに完了ハンドラを呼び出す関数3のコードがあります。 SyncfetchContacts

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

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) 
//   } 
    } 
} 
関連する問題