Swift closure capture and inout variables - swift

Consider the following code:
func foo(inout success: Bool) -> (()->()) {
return { _ in
success = true
print (success)
}
}
var success = false
let closure = foo(&success)
closure() //prints "true"
print(success) //prints "false"
The closure appears to be creating a copy of success and does not change the original. Why is this taking place? I had assumed that the closure would point to the original because we are passing an inout variable.

It makes sense that this wouldn't update your success variable because your inout parameter is a parameter of foo, not of the closure itself. You get the desired behavior if you make the inout parameter a parameter of the closure:
var success = false
let closure = { (inout flag: Bool) -> () in
flag = true
print(flag)
}
closure(&success) //prints "true"
print(success) //prints "true"
This pattern also works with the function, too, as long as you keep the inout parameter a parameter of the closure:
func foo() -> ((inout Bool)->()) {
return { flag in
flag = true
print (flag)
}
}
var success = false
let closure = foo()
closure(&success) //prints "true"
print(success) //prints "true"
You also get the desired behavior if you use a reference type:
class BooleanClass: CustomStringConvertible {
var value: Bool
init(value: Bool) {
self.value = value
}
var description: String { return "\(value)" }
}
func foo(flag: BooleanClass) -> (()->()) {
return {
flag.value = true
print (flag)
}
}
let success = BooleanClass(value: false)
let closure = foo(success)
closure() //prints "true"
print(success) //prints "true"

This seems to be covered by Swift Evolution proposal 0035, and is considered a bug.
The document there refers to the inout parameter to the function as "a shadow copy that is written back to the argument when the callee returns". This seems to mean that there is, in essence, a temporary variable named success in the executing context of foo(). The value of that temp is then put into the outer success only when foo() returns.
Since in your foo(), the closure has not run when foo() returns, the value of the "shadow copy" has not changed. The outer success keeps its value.
The important part is that the closure has captured the shadow copy, not the outer success as you expect. So when the closure finally runs, that variable's value does change, but it no longer has any connection to the original outer success.
The proposal uses this snippet to demonstrate:
func captureAndEscape(inout x: Int) -> () -> Void {
let closure = { x += 1 }
closure()
return closure
}
var x = 22
let closure = captureAndEscape(&x)
print(x) // => 23
closure()
print("still \(x)") // => still 23

Related

Using generic methods in protocols Swift

I believe I have some misunderstanding of how generics work. I have the protocol:
protocol CommandProtocol {
func execute<T>() -> T
func unExecute<T>() -> T
}
And a class that conforms to it:
class CalculatorCommand: CommandProtocol {
...
func execute<String>() -> String {
return calculator.performOperation(operator: `operator`, with: operand) as! String
}
func unExecute<Double>() -> Double {
return calculator.performOperation(operator: undo(operator: `operator`), with: operand) as! Double
}
...
}
The calculator.performOperation() method actually returns Double, but here I just try to play with generics so I replace return type from Double to String.
After that, I have a class which invokes these methods:
class Sender {
...
// MARK: - Public methods
func undo() -> Double {
if current > 0 {
current -= 1
let command = commands[current]
return command.unExecute()
}
return 0
}
func redo() -> Double? {
if current < commands.count {
let command = commands[current]
current += 1
let value: Double = command.execute()
print(type(of: value))
return command.execute()
}
return nil
}
...
}
In the undo() method everything works as expected (one thing that I did not understand fully is how Swift really knows whether the unExecute value will return Double or not, or compiler infers it based on the undo() return type?)
But in the redo() method, I am calling the execute() method which returns String, but the method expects Double, so I thought that my program would crash, but not, it works totally fine as if execute() method returns Double.
Please, could someone explain to me what exactly happens under the cover of this code? Thank you in advance.
You are correct that you misunderstand generics. First, let's look at this protocol:
protocol CommandProtocol {
func execute<T>() -> T
func unExecute<T>() -> T
}
This says "no matter what type the caller requests, this function will return that type." That's impossible to successfully implement (by "successfully" I mean "correctly returns a value in all cases without crashing"). According this protocol, I'm allowed to write the following code:
func run(command: CommandProtocol) -> MyCustomType {
let result: MyCustomType = command.execute()
return result
}
There's no way to write an execute that will actually do that, no matter what MyCustomType is.
Your confusion is compounded by a subtle syntax mistake:
func execute<String>() -> String {
This does not mean "T = String," which is what I think you expect it to mean. It creates a type variable called String (that has nothing to do with Swift's String type), and it promises to return it. when you later write as! String, that means "if this values isn't compatible with the type requested (not "a string" but whatever was requested by the caller), then crash.
The tool that behaves closer to what you want here is an associated type. You meant to write this:
protocol CommandProtocol {
associatedType T
func execute() -> T
func unExecute() -> T
}
But this almost certainly won't do what you want. For example, with that, it's impossible to have an array of commands.
Instead what you probably want is a struct:
struct Command {
let execute: () -> Void
let undo: () -> Void
}
You then make Commands by passing closures that do what you want:
let command = Command(execute: { self.value += 1 },
undo: { self.value -= 1 })
Alternately, since this is a calculator, you could do it this way:
struct Command {
let execute: (Double) -> Double
let undo: (Double) -> Double
}
let command = Command(execute: { $0 + 1 }, undo: { $0 - 1 })
Then your caller would look like:
value = command.execute(value)
value = command.undo(value)
You think this returns a Swift.Double, but no. This code is no different than using T instead of Double. Swift does not require the names of generic placeholders to match what you put in a protocol.
func unExecute<Double>() -> Double {
return calculator.performOperation(operator: undo(operator: `operator`), with: operand) as! Double
}
You're not actually looking for generic methods. You want this, instead.
protocol CommandProtocol {
associatedtype ExecuteValue
associatedtype UnExecuteValue
func execute() -> ExecuteValue
func unExecute() -> UnExecuteValue
}

Swift closures - force a closure to always complete

Is it possible to force a closure to be completed? In the same way that a function with a return value MUST always return, it would be ace if there was a way to force a closure to contain the syntax necessary to always complete.
For example, this code will not compile because the function does not always return a value:
func isTheEarthFlat(withUserIQ userIQ: Int) -> Bool {
if userIQ > 10 {
return false
}
}
In the exact same way, I would like to define a function with a closure, which will also not compile if the closure never returns. For example, the code below might never return a completionHandler:
func isTheEarthFlat(withUserIQ userIQ: Int, completionHandler: (Bool) -> Void) {
if userIQ > 10 {
completionHandler(false)
}
}
The code above compiles, but I was wondering if there is a keyword which enforces that the closure sends a completion handler in all cases. Maybe it has something to do with the Void in the above function?
No, there is no language construct that will result in a compiler error if you forget (or don't need) to call the completion handler under all possible conditions like a return statement.
It's an interesting idea that might make a useful enhancement to the language. Maybe as a required keyword somewhere in the parameter declaration.
There is no special keyword for what you want. But there is an interesting approach you can take into consideration, that won't compile:
func isTheEarthFlat(withUserIQ userIQ: Int, completionHandler: (Bool) -> Void) {
let result: Bool
defer {
completionHandler(result)
}
if userIQ > 10 {
result = false
}
}
that will do and is completionHandler is forced to be called:
func isTheEarthFlat(withUserIQ userIQ: Int, completionHandler: (Bool) -> Void) {
let result: Bool
defer {
completionHandler(result)
}
if userIQ > 10 {
result = false
} else {
result = true
}
}
Not sure it's a good pattern to use.
Here is an interesting technique I thought of. You define GuarenteedExecution and GuarenteedExecutionResult types.
A GuarenteedExecution is a wrapper around a closure, which is to be used in a context where the execution of the closure must be guaranteed.
The GuarenteedExecutionResult is the result of executing a GuarenteedExecution. The trick is to have a desired function, e.g. isTheEarthFlat, return a GuarenteedExecutionResult. The only way to obtain a GuarenteedExecutionResult instance is by calling execute(argument:) on a GuarenteedExecution. Effectively, the type checker features responsible for guaranteeing a return, are now being used to guarantee the execution of GuarenteedExecution.
struct GuarenteedExecutionResult<R> {
let result: R
fileprivate init(result: R) { self.result = result }
}
struct GuarenteedExecution<A, R> {
typealias Closure = (A) -> R
let closure: Closure
init(ofClosure closure: #escaping Closure) {
self.closure = closure
}
func execute(argument: A) -> GuarenteedExecutionResult<R> {
let result = closure(argument)
return GuarenteedExecutionResult(result: result)
}
}
Example usage, in a seperate file (so as to not have access to GuarenteedExecutionResult.init):
let guarenteedExecutionClosure = GuarenteedExecution(ofClosure: {
print("This must be called!")
})
func doSomething(guarenteedCallback: GuarenteedExecution<(), ()>)
-> GuarenteedExecutionResult<()> {
print("Did something")
return guarenteedCallback.execute(argument: ())
}
_ = doSomething(guarenteedCallback: guarenteedExecutionClosure)

Updating an inout param async does not update reference [duplicate]

I'm trying to insert functions with inout parameter to append data received from async callback to an outside array. However, it does not work. And I tried everything I know to find out why - with no luck.
As advised by #AirspeedVelocity, I rewrote the code as follows to remove unnecessary dependencies. I also use an Int as the inout parameter to keep it simple.The output is always:
c before: 0
c after: 1
I'm not able to figure out what goes wrong here.
func getUsers() {
let u = ["bane", "LiweiZ", "rdtsc", "ssivark", "sparkzilla", "Wogef"]
var a = UserData()
a.userIds = u
a.dataProcessor()
}
struct UserData {
var userIds = [String]()
var counter = 0
mutating func dataProcessor() -> () {
println("counter: \(counter)")
for uId in userIds {
getOneUserApiData(uriBase + "user/" + uId + ".json", &counter)
}
}
}
func getOneUserApiData(path: String, inout c: Int) {
var req = NSURLRequest(URL: NSURL(string: path)!)
var config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
var session = NSURLSession(configuration: config)
var task = session.dataTaskWithRequest(req) {
(data: NSData!, res: NSURLResponse!, err: NSError!) in
println("c before: \(c)")
c++
println("c after: \(c)")
println("thread on: \(NSThread.currentThread())")
}
task.resume()
}
Thanks.
Sad to say, modifying inout parameter in async-callback is meaningless.
From the official document:
Parameters can provide default values to simplify function calls and can be passed as in-out parameters, which modify a passed variable once the function has completed its execution.
...
An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.
Semantically, in-out parameter is not "call-by-reference", but "call-by-copy-restore".
In your case, counter is write-backed only when getOneUserApiData() returns, not in dataTaskWithRequest() callback.
Here is what happened in your code
at getOneUserApiData() call, the value of counter 0 copied to c1
the closure captures c1
call dataTaskWithRequest()
getOneUserApiData returns, and the value of - unmodified - c1 is write-backed to counter
repeat 1-4 procedure for c2, c3, c4 ...
... fetching from the Internet ...
callback is called and c1 is incremented.
callback is called and c2 is incremented.
callback is called and c3 is incremented.
callback is called and c4 is incremented.
...
As a result counter is unmodified :(
Detailed explaination
Normally, in-out parameter is passed by reference, but it's just a result of compiler optimization. When closure captures inout parameter, "pass-by-reference" is not safe, because the compiler cannot guarantee the lifetime of the original value. For example, consider the following code:
func foo() -> () -> Void {
var i = 0
return bar(&i)
}
func bar(inout x:Int) -> () -> Void {
return {
x++
return
}
}
let closure = foo()
closure()
In this code, var i is freed when foo() returns. If x is a reference to i, x++ causes access violation. To prevent such race condition, Swift adopts "call-by-copy-restore" strategy here.
Essentially it looks like you’re trying to capture the “inout-ness” of an input variable in a closure, and you can’t do that – consider the following simpler case:
// f takes an inout variable and returns a closure
func f(inout i: Int) -> ()->Int {
// this is the closure, which captures the inout var
return {
// in the closure, increment that var
return ++i
}
}
var x = 0
let c = f(&x)
c() // these increment i
c()
x // but it's not the same i
At some point, the variable passed in ceases to be x and becomes a copy. This is probably happening at the point of capture.
edit: #rintaro’s answer nails it – inout is not in fact semantically pass by reference
If you think about it this makes sense. What if you did this:
// declare the variable for the closure
var c: ()->Int = { 99 }
if 2+2==4 {
// declare x inside this block
var x = 0
c = f(&x)
}
// now call c() - but x is out of scope, would this crash?
c()
When closures capture variables, they need to be created in memory in such a way that they can stay alive even after the scope they were declared ends. But in the case of f above, it can’t do this – it’s too late to declare x in this way, x already exists. So I’m guessing it gets copied as part of the closure creation. That’s why incrementing the closure-captured version doesn’t actually increment x.
I had a similar goal and ran into the same issue where results inside the closure were not being assigned to my global inout variables. #rintaro did a great job of explaining why this is the case in a previous answer.
I am going to include here a generalized example of how I worked around this. In my case I had several global arrays that I wanted to assign to within a closure, and then do something each time (without duplicating a bunch of code).
// global arrays that we want to assign to asynchronously
var array1 = [String]()
var array2 = [String]()
var array3 = [String]()
// kick everything off
loadAsyncContent()
func loadAsyncContent() {
// function to handle the query result strings
// note that outputArray is an inout parameter that will be a reference to one of our global arrays
func resultsCallbackHandler(results: [String], inout outputArray: [String]) {
// assign the results to the specified array
outputArray = results
// trigger some action every time a query returns it's strings
reloadMyView()
}
// kick off each query by telling it which database table to query and
// we're also giving each call a function to run along with a reference to which array the results should be assigned to
queryTable("Table1") {(results: [String]) -> Void in resultsCallbackHandler(results, outputArray: &self.array1)}
queryTable("Table2") {(results: [String]) -> Void in resultsCallbackHandler(results, outputArray: &self.array2)}
queryTable("Table3") {(results: [String]) -> Void in resultsCallbackHandler(results, outputArray: &self.array3)}
}
func queryTable(tableName: String, callback: (foundStrings: [String]) -> Void) {
let query = Query(tableName: tableName)
query.findStringsInBackground({ (results: [String]) -> Void in
callback(results: results)
})
}
// this will get called each time one of the global arrays have been updated with new results
func reloadMyView() {
// do something with array1, array2, array3
}
#rintaro perfectly explained why it doesn't work, but if you really want to do that, using UnsafeMutablePointer will do the trick:
func getOneUserApiData(path: String, c: UnsafeMutablePointer<Int>) {
var req = NSURLRequest(URL: NSURL(string: path)!)
var config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
var session = NSURLSession(configuration: config)
var task = session.dataTaskWithRequest(req) {
(data: NSData!, res: NSURLResponse!, err: NSError!) in
println("c before: \(c.memory)")
c.memory++
println("c after: \(c.memory)")
println("thread on: \(NSThread.currentThread())")
}
task.resume()
}

Inout parameter in async callback does not work as expected

I'm trying to insert functions with inout parameter to append data received from async callback to an outside array. However, it does not work. And I tried everything I know to find out why - with no luck.
As advised by #AirspeedVelocity, I rewrote the code as follows to remove unnecessary dependencies. I also use an Int as the inout parameter to keep it simple.The output is always:
c before: 0
c after: 1
I'm not able to figure out what goes wrong here.
func getUsers() {
let u = ["bane", "LiweiZ", "rdtsc", "ssivark", "sparkzilla", "Wogef"]
var a = UserData()
a.userIds = u
a.dataProcessor()
}
struct UserData {
var userIds = [String]()
var counter = 0
mutating func dataProcessor() -> () {
println("counter: \(counter)")
for uId in userIds {
getOneUserApiData(uriBase + "user/" + uId + ".json", &counter)
}
}
}
func getOneUserApiData(path: String, inout c: Int) {
var req = NSURLRequest(URL: NSURL(string: path)!)
var config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
var session = NSURLSession(configuration: config)
var task = session.dataTaskWithRequest(req) {
(data: NSData!, res: NSURLResponse!, err: NSError!) in
println("c before: \(c)")
c++
println("c after: \(c)")
println("thread on: \(NSThread.currentThread())")
}
task.resume()
}
Thanks.
Sad to say, modifying inout parameter in async-callback is meaningless.
From the official document:
Parameters can provide default values to simplify function calls and can be passed as in-out parameters, which modify a passed variable once the function has completed its execution.
...
An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.
Semantically, in-out parameter is not "call-by-reference", but "call-by-copy-restore".
In your case, counter is write-backed only when getOneUserApiData() returns, not in dataTaskWithRequest() callback.
Here is what happened in your code
at getOneUserApiData() call, the value of counter 0 copied to c1
the closure captures c1
call dataTaskWithRequest()
getOneUserApiData returns, and the value of - unmodified - c1 is write-backed to counter
repeat 1-4 procedure for c2, c3, c4 ...
... fetching from the Internet ...
callback is called and c1 is incremented.
callback is called and c2 is incremented.
callback is called and c3 is incremented.
callback is called and c4 is incremented.
...
As a result counter is unmodified :(
Detailed explaination
Normally, in-out parameter is passed by reference, but it's just a result of compiler optimization. When closure captures inout parameter, "pass-by-reference" is not safe, because the compiler cannot guarantee the lifetime of the original value. For example, consider the following code:
func foo() -> () -> Void {
var i = 0
return bar(&i)
}
func bar(inout x:Int) -> () -> Void {
return {
x++
return
}
}
let closure = foo()
closure()
In this code, var i is freed when foo() returns. If x is a reference to i, x++ causes access violation. To prevent such race condition, Swift adopts "call-by-copy-restore" strategy here.
Essentially it looks like you’re trying to capture the “inout-ness” of an input variable in a closure, and you can’t do that – consider the following simpler case:
// f takes an inout variable and returns a closure
func f(inout i: Int) -> ()->Int {
// this is the closure, which captures the inout var
return {
// in the closure, increment that var
return ++i
}
}
var x = 0
let c = f(&x)
c() // these increment i
c()
x // but it's not the same i
At some point, the variable passed in ceases to be x and becomes a copy. This is probably happening at the point of capture.
edit: #rintaro’s answer nails it – inout is not in fact semantically pass by reference
If you think about it this makes sense. What if you did this:
// declare the variable for the closure
var c: ()->Int = { 99 }
if 2+2==4 {
// declare x inside this block
var x = 0
c = f(&x)
}
// now call c() - but x is out of scope, would this crash?
c()
When closures capture variables, they need to be created in memory in such a way that they can stay alive even after the scope they were declared ends. But in the case of f above, it can’t do this – it’s too late to declare x in this way, x already exists. So I’m guessing it gets copied as part of the closure creation. That’s why incrementing the closure-captured version doesn’t actually increment x.
I had a similar goal and ran into the same issue where results inside the closure were not being assigned to my global inout variables. #rintaro did a great job of explaining why this is the case in a previous answer.
I am going to include here a generalized example of how I worked around this. In my case I had several global arrays that I wanted to assign to within a closure, and then do something each time (without duplicating a bunch of code).
// global arrays that we want to assign to asynchronously
var array1 = [String]()
var array2 = [String]()
var array3 = [String]()
// kick everything off
loadAsyncContent()
func loadAsyncContent() {
// function to handle the query result strings
// note that outputArray is an inout parameter that will be a reference to one of our global arrays
func resultsCallbackHandler(results: [String], inout outputArray: [String]) {
// assign the results to the specified array
outputArray = results
// trigger some action every time a query returns it's strings
reloadMyView()
}
// kick off each query by telling it which database table to query and
// we're also giving each call a function to run along with a reference to which array the results should be assigned to
queryTable("Table1") {(results: [String]) -> Void in resultsCallbackHandler(results, outputArray: &self.array1)}
queryTable("Table2") {(results: [String]) -> Void in resultsCallbackHandler(results, outputArray: &self.array2)}
queryTable("Table3") {(results: [String]) -> Void in resultsCallbackHandler(results, outputArray: &self.array3)}
}
func queryTable(tableName: String, callback: (foundStrings: [String]) -> Void) {
let query = Query(tableName: tableName)
query.findStringsInBackground({ (results: [String]) -> Void in
callback(results: results)
})
}
// this will get called each time one of the global arrays have been updated with new results
func reloadMyView() {
// do something with array1, array2, array3
}
#rintaro perfectly explained why it doesn't work, but if you really want to do that, using UnsafeMutablePointer will do the trick:
func getOneUserApiData(path: String, c: UnsafeMutablePointer<Int>) {
var req = NSURLRequest(URL: NSURL(string: path)!)
var config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
var session = NSURLSession(configuration: config)
var task = session.dataTaskWithRequest(req) {
(data: NSData!, res: NSURLResponse!, err: NSError!) in
println("c before: \(c.memory)")
c.memory++
println("c after: \(c.memory)")
println("thread on: \(NSThread.currentThread())")
}
task.resume()
}

optional closure and check if it is nil

So what I want to have is a class that may get a closure passed to it in a function, it may also at some point want to disregard a that closure. How can I check if the closure variable is set and hwo can I delete it when I am done with it?
Cannot invoke '!=' with an argument list of type '(#lvalue (sucsess:
Bool!, products: [AnyObject]!) -> ()?, NilLiteralConvertible)' Type
'(sucsess: Bool!, products: [AnyObject]!) -> ()?' does not conform to
protocol 'NilLiteralConvertible'
class someClass{
//typealias completionHandlerClosureType = (sucsess:Bool!, items:[AnyObject]!)->()
var completionHandler:(sucsess:Bool!, items:[AnyObject]!)->()?
var hitpoints = 100
var someset = ["oh no!","avenge me!"]
init(){}
func getHitFunc(impact:Int, passedCompletionsHandler:(sucsess:Bool!, items:[AnyObject]!)->()){
completionHandler = passedCompletionsHandler
hitpoints = hitpoints - impact
}
func checkIfDead{
if hitpoints<=0 { // The error received
if completionHandler != nil{// Cannot invoke '!=' with an argument list of type
//'(#lvalue (sucsess: Bool!, products: [AnyObject]!) -> ()?, NilLiteralConvertible)'
//run the handler if dead
completionHandler(sucsess: true, items: someset)
//do not run it again
completionHandler = nil //Type '(sucsess: Bool!, products: [AnyObject]!) -> ()?' does not conform to protocol 'NilLiteralConvertible'
}
}
else{
completionHandler = nil //Type '(sucsess: Bool!, products: [AnyObject]!) -> ()?' does not conform to protocol 'NilLiteralConvertible'
}
}
}
You need to wrap your closure signature in parentheses to make the closure itself optional. The way it's written now, the closure returns an optional Void (which doesn't really make sense).
var completionHandler: ((sucsess:Bool!, items:[AnyObject]!)->())?
Some style points and revisions to your example code:
// Capitalize class names so it's clear what's a class
class SomeClass {
// "success" has two "c"s
var completionHandler: ((success:Bool!, items:[AnyObject]!)->())?
var hitpoints = 100
var someset = ["oh no!","avenge me!"]
init() { }
func getHitFunc(impact:Int, passedCompletionsHandler:(success:Bool!, items:[AnyObject]!)->()){
completionHandler = passedCompletionsHandler
hitpoints = hitpoints - impact
}
// You were missing the argument list here:
func checkIfDead() {
if hitpoints <= 0 {
// Rather than checking to see if the completion handler exists, you can
// just call it using optional syntax like this:
completionHandler?(success: true, items: someset)
}
completionHandler = nil
}
}
First, in your declaration of the completion handler, you need to declare the whole thing as optional with the use of parentheses:
var completionHandler: ((_ success: Bool, _ items: [Any]?) -> ())?
Or, perhaps better, you can replace that final () with Void:
var completionHandler: ((_ success: Bool, _ items: [Any]?) -> Void)?
Also, note, I don't think you meant to make the Bool optional (because if the closure exists, you presumably always pass a success value of true or false). Clearly, the array of items might well be optional.
Anyway, when done, you'd just make sure to unwrap that optional:
func checkIfDead() {
if hitpoints <= 0 {
completionHandler?(true, items)
}
completionHandler = nil
}
This performs the closure if and only if it is not nil, avoiding the need to explicitly check if it was nil.
For what it's worth, this might be a case where your typealias might make this less confusing:
typealias CompletionHandlerClosureType = (_ success: Bool, _ items: [Any]?) -> Void
Then the property is simply:
var completionHandler: CompletionHandlerClosureType?
The function that takes this completionHandler as a optional parameter could do:
func startSomeProcess(passedCompletionHandler: CompletionHandlerClosureType?) {
completionHandler = passedCompletionHandler
// do whatever else you want
}
and then the final completion logic is unchanged:
func finishSomeProcess() {
completionHandler?(true, items)
completionHandler = nil
}
(Note, the above has been modified for Swift 3. Please see previous revision of this answer if you want to see Swift 2 renditions.)