How to save Closure completion handler for calling later?

I am working on converting this tutorial on buying apps to Swift and ran into a problem while trying to save a completion handler. We need to save this completion handler so that it can be called later. I cannot figure out how to save a copy of the closure from the arguments. In particular, I believe that I need to copy it, but Xcode claims that this object does not have a copy function.

I defined it like this:

typealias RequestProductsCompletionHandler = (success: Bool, products: NSArray) -> Void 

Here I declare a property for it:

 var completionHandler: RequestProductsCompletionHandler? 

Then I need to save the passed completion handler to my property:

 func requestProductsWithCompletionHandler(completionBlock: RequestProductsCompletionHandler) -> Void { //self.completionHandler = completionBlock.copy() //problem: RequestProductsCompletionHandler does not have a member named copy } 

Here's how it was done in the Obj-C tutorial:

 typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products); RequestProductsCompletionHandler _completionHandler; - (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler { _completionHandler = [completionHandler copy]; } 

And later it is used like this:

 _completionHandler(YES, skProducts); _completionHandler = nil; 

EDIT: I deleted .copy () to prevent the error (I also needed to make NSArray optional so I could set it to nil later). My question is, will it work as expected without explicitly copying it? I do not believe this will happen because Apple has stated that closures are reference types . This will keep the link to the original closure, which I do not want to do. How to force a copy?

+5
source share
1 answer

Yes. It will work as expected.

Whenever you call requestProductsWithCompletionHandler , you create a closure and pass it to this function. And, as you mentioned, when you install completionHandler , you actually set it as a reference to this closure.

In Objective-C, in order to save the block as ivar, you had to copy the block. This is because the block is first in the memory of the stack where it was defined. And the copy moved it to the heap memory so that it could be used

+4
source

Source: https://habr.com/ru/post/1201943/


All Articles