2017-05-25 34 views
0

調用初始化時我具有定義了一個封閉件這樣的功能:夫特3加​​入@esaping屬性崩潰中的NSOperation

func synchronizeData(completion externalCompletion: RequestsCompletionHandler?) { 

    let closure = { 

     (operationCompletion:@escaping()->Void) in 

     assert(Thread.isMainThread, "must be the main thread") 

     /* 
     Internal (non-optional) completion handler 
     */ 
     let internalCompletion: RequestsCompletionHandler = { 

      (success, newData, decommissionRequired, errors) -> Void in 

      /* 
      Synchronization is finished. Firstly, call either the external completion handler or the delegate 
      */ 
      if let externalCompletion = externalCompletion { 

       externalCompletion(success, newData, decommissionRequired, errors) 
      } 
      else { 

       self.delegate?.synchroniationInteractor(self, didSynchronizeDataWithStatus: success, dataIsNew: newData, decommissionRequired: decommissionRequired, error: errors.last) 
      } 

      /* 
      Now call the closure operation's completion handler 
      */ 
      operationCompletion() 
     } 

     /* 
     The synchronization itself 
     */ 
     guard let _ = self.keychain.retrieveActivationIdentifiers() else { 

      internalCompletion(false, false, false, [NSError(domain: "", code: 0, userInfo: ["reason" : "unable to retrieve credentials"])]) 
      return 
     } 

     var errors :[NSError] = [] 

     var numberOfRequests = 0 
     var completedRequests = 0 

     var decommissionRequired: Bool? 

     /* 
     Synchronization results handler. Regardless of success for fail, increase completed requests counter and append any errors to array, if final request call main completion block 
     */ 
     let handleCompletedRequests = { 

      (error: NSError?) -> Void in 

//   assert(NSThread.isMainThread(), "must be the main thread") 

      if let error = error { 
       errors.append(error) 
      } 

      completedRequests += 1 

      if(completedRequests >= numberOfRequests) { 

       internalCompletion(errors.count == 0, true, decommissionRequired, errors) 

       /* 
       Decrement operations counter 
       */ 
       self.manageBusy(retain: false) 
      } 
     } 

     /* 
     Increment operations counter 
     */ 
     self.manageBusy(retain: true) 

     /* 
     Do the actual synchronization. 
     Fetch the Patient Data first 
     */ 
     self.fetchPatientDataInternal { 

      (success, newData, error) -> Void in 

      numberOfRequests = 6 

      //Fetch Patient Schedule 
      self.fetchPatientScheduleInternal { 

       (success, newData, error) -> Void in 
       handleCompletedRequests(error) 
      } 

      //Fetch Patient Thresholds 
      self.fetchPatientThresholdInternal { 

       (success, newData, error) -> Void in 
       handleCompletedRequests(error) 
      } 

      //Fetch Patient Device Settings 
      self.fetchPatientDeviceSettingsInternal { 

       (success, newData, decommissionReq, error) -> Void in 

       decommissionRequired = decommissionReq 
       handleCompletedRequests(error) 
      } 

      // Device Checkin 
      self.deviceCheckInInternal { 

       (success, newData, error) -> Void in 
       handleCompletedRequests(error) 
      } 

      // Upload Vitals 
      self.uploadPendingVitalsInternal { 

       (success, newData, error) -> Void in 
       handleCompletedRequests(error) 
      } 

      //Upload Health sessions 
      self.uploadPendingHealthSessionsInternal { 

       (success, newData, error) -> Void in 
       handleCompletedRequests(error) 
      } 
     } 
    } 
    let operation = CIAsyncronousOperation.init(closure: closure as! (()->Void)-> Void) 
    operation.name = "Data Synchronization" 
    isolationQueue.addOperation(operation) 
} 

當我們調用該線在上述功能即

let operation = CIAsyncronousOperation.init(closure: closure as! (()->Void)-> Void) 

該應用程序與以下信息崩潰:

0x00000001003b083c CIAppliance`部分申請轉發CIAppliance.SynchronizationI (同步數據(完成:Swift.Optional <(Swift.Bool,Swift.Optional,Swift.Optional,Swift.Array < __ObjC.NSError>) - >()>) - >())。(closure#1)在SynchronizationInteractor.swift

的CIAsyncronousOperation init的定義如下:

init(closure aClosure: @escaping (()->Void)-> Void) 
{ 

     closure = aClosure 
} 

我無法找出崩潰的原因。它是由於新的Swift 3語法改變而導致問題嗎?

回答

0

如果您不得不強制轉換該函數,那麼很可能您的函數簽名不正確。如果CIAsyncronousOperation定義如下,它將編譯。參數aClosure的函數和函數都需要設置爲@escaping

class CIAsyncronousOperation { 
    init(closure aClosure: @escaping (@escaping()->Void)->Void) 
    { 
     closure = aClosure 
    } 
    var closure : (@escaping()->Void)-> Void; 
} 
+0

謝謝。我仍然無法掌握@escaping。可能b我應該花更多的時間來理解它 – user2122350

+0

如果在函數返回後可以調用它,則需要將閉包設置爲@escaping,即如果它轉義該函數。 – Spads