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語法改變而導致問題嗎?
謝謝。我仍然無法掌握@escaping。可能b我應該花更多的時間來理解它 – user2122350
如果在函數返回後可以調用它,則需要將閉包設置爲@escaping,即如果它轉義該函數。 – Spads