Reputation: 83
I know about the changes in Swift 3 where @nonescaping is default behaviour for closures.
I have successfully changed much of my code regarding the changes but I have one part of my code where I am not able to get rid of the Closure use of non-escaping parameter may allow it to escape compilation error.
I have tried adding @escaping to both the updateHandler parameter and the UpdatedInProgressHandler typealias but it does not seem to be enough.
Anyone able to help me figuring out the reason for my problem?
The code where typealiases and the function is defined:
// Typealiases used to clean up closures
typealias UpdateInProgressCompletion = () -> ()
typealias UpdateInProgressCancelCompletion = () -> ()
typealias UpdateInProgressHandler = ((_ completed: @escaping UpdateInProgressCompletion) -> ()) -> ()
// Method for wrapping the presentation and dismissal of the custom alert controller
func presentUpdateInProgress(_ taskIdentifier: String?, alertMessage: String?, alertHeader: String? = nil, updateHandler: @escaping UpdateInProgressHandler, cancel cancelHandler: UpdateInProgressCancelCompletion? = nil) {
let updateInProgressAlert = self.updateInProgressAlert( taskIdentifier, alertMessage: alertMessage, alertHeader: alertHeader ) { action in
cancelHandler?()
Logger.debug("User cancelled update")
}
updateInProgressAlert.present(completion: nil)
updateHandler { (completion) in
updateInProgressAlert.dismiss(completion: completion)
}
}
The code where I get the "Closure use of non-escaping parameter "updateCompleted" may allow if to escape" error when calling presentUpdateInProgress function.
self.presentUpdateInProgress(taskIdentifier, alertMessage: "My alert message", updateHandler: { (updateCompleted) -> () in
let task = CreateModelTask(completionHandler: { (resultObject) -> () in
updateCompleted { // this generates the error
//Do some stuff with received result
}
})
task.taskIdentifier = taskIdentifier
SyncManager.sharedManager.addTaskToQueue(task)
})
Upvotes: 4
Views: 2665
Reputation: 80951
updateCompleted
is of type (_ completed: @escaping UpdateInProgressCompletion) -> ()
, which as it's a function parameter itself, means that it is non-escaping by default (note that 'non-escaping by default' behaviour is only applicable to function closure arguments, see this Q&A, as well as its dupe target on the topic).
Therefore in order to allow updateCompleted
to escape, you need to mark (_ completed: @escaping UpdateInProgressCompletion) -> ()
as @escaping
in your typealias
:
typealias UpdateInProgressHandler = (@escaping (_ completed: @escaping UpdateInProgressCompletion) -> ()) -> ()
Upvotes: 3