I am little bit confused about escaping closure - ios

I am new to swift and trying to learn when I saw apple doc in it there is a definition about escaping closure like:
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write #escaping before the parameter’s type to indicate that the closure is allowed to escape.
# other hand I saw a blog where blogger explained about completion handler like:
There are times you put a closure as one of the parameters, but you only want to execute the closure after the function returns. For example, what if you want to print “Hello, world” only after you’ve completely switched to the next ViewController?
So I want to know if completion handler and escaping closure are same or what?

I want to know that completion handler and escaping closure are same
or what?
Completion and Error Handlers are related to a process that should be done after executing -and returning- a chunk of code (function):
Completion handlers are callbacks that allow a client to perform some
action when a framework method or function completes its task.
https://developer.apple.com/library/content/featuredarticles/Short_Practical_Guide_Blocks/
which are -logically- representation of escaping closures.
So, referring to the escaping closures definition, a completion handler is by default is an escaping closures.
For reviewing example(s), you might want to check this answer. Also, if you think that you need more description about what is the escaping closure, you might wan to check this Q&A.

Completion handlers are one example where escaping closures are passed, but they are not the only one.
In fact, the concept of a completion handler works on a different level than the concept of an escaping closure.
Escaping Closure
The closure is stored, and may be invoked at some time in the future.
This is in contrast to a non-escaping closure, where the closure gets called immediately or not at all.
The difference between escaping and non-escaping closure is important for memory management. For non-escaping closures, the compiler knows that any resources used by the closure aren't used anymore after the call.
Completion Handler
A completion handler is a closure that gets called once an operation is finished.
Operations that use completion handlers often are long-running and work on different threads. While such an operation is running, your program can continue with its control flow, thereby making the program more responsive. For example, if you call URLSession.downloadTask(withResumeData:completionHandler:), you will schedule a new download task in URLSession. Downloading may take a while, depending on your connectivity status and other factors, and only once the download was finished your completion handler gets called.
The way such operations are implemented is usually, that they store the completion handler somewhere, perform the operation, and then call the completion handler. Therefore, completion handlers are usually escaping closures.

Related

UICollectionview.performBatchUpdates updates block does not need explicit use of self in capture list

When using collectionview.performBatchUpdates, the updates block does not need explicit self like below image.
The method's docs are here. https://developer.apple.com/documentation/uikit/uicollectionview/1618045-performbatchupdates
My guesss is that performBatchUpdates's updates block life cycle is garanteed shorter than collectionView. And the updates block called using withoutActuallyEscaping.
Is there anyone have clear answer?
The answer is simple. Because it's not a escaping closure
The animate closure is escaping, while the performBatchUpdates closure is not.
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write #escaping before the parameter’s type to indicate that the closure is allowed to escape
An escaping closure that refers to self needs special consideration if self refers to an instance of a class. Capturing self in an escaping closure makes it easy to accidentally create a strong reference cycle. For information about reference cycles, see Automatic Reference Counting.
Normally, a closure captures variables implicitly by using them in the body of the closure, but in this case you need to be explicit. If you want to capture self, write self explicitly when you use it, or include self in the closure’s capture list. Writing self explicitly lets you express your intent, and reminds you to confirm that there isn’t a reference cycle.

How do I break out of the async cycle?

In Dart, you can tell the VM to wait for a Future by calling await.
The thing is that you can only call await in an async function, which returns a ... Future.
So if I have a function which doesn't take a long time to run, and has to be run in a function who's type is not async, how do I break out of the async chain?
There is no such thing as breaking out of the async cycle. It's possible to have sync functions to call async code, but the result of the async code won't be available yet when the sync function returns.
The difference between a synchronous function and an asynchronous function is that the former is done when it returns, and the latter is still working in the background when it returns, which is why it returns a Future which will complete when it's really done.
That is the distinction - an asynchronous function is one that returns a Future. The async marker is not what makes the function asynchronous, it's just one way of implementing an asynchronous function. You can also have functions without the async marker which return a Future.
You can call an asynchronous function from a synchronous function. However, there is no way for the synchronous function to delay its return, so it must return before the future completes. It can set up a listener on the future, future.then((value) { doSomethingWith(value); }), but that listener will certainly only be called after the synchronous function has returned. That then-call also returns a future, so the synchronous function has to ignore some Future. That's fine. You are allowed to ignore a future when you don't need the result.
Whatever you do, you can't get the result of a Future in a synchronous function before it returns.

Can you dispatch a non-escaping closure function asynchronously?

My brief understanding of the difference between escaping and non-escaping closures:
Escaping closures are invoked after the function returns. From what I can tell, this is similar to the way callbacks are handled in node.js — the function returns immediately, they execute asynchronously, and the result of the long-running operation inside the function is handled when the closure/completion block/callback is called.
Non-escaping closures appear to be execute synchronously, where the function itself doesn't return until the long-running operation is complete.
(Did I get that right?)
Reading the change log and justification for moving from Swift 2's #noescape to Swift 3's #escaping (in SE-0103), it appears you can asynchronously dispatch non-escaping closures.
Is this true? Possible?
Can you dispatch a non-escaping closure function asynchronously? If so, how?
Bonus points — I really want to understand why both escaping and non-escaping closures exist:
Is there a practical use-case for asynchronously dispatching a non-escaping closure in place of an escaping closure?
In the design proposal, it suggests that functional programming benefits from non-escaping (read: synchronous?) being the default. Is this true? Why?
Is there any similarity between non-escaping closures and a promise in node.js?
If I'm wrong about all of this, why not just call it #async instead of #escaping?
I can't conceive of how an asynchronously dispatched function can be non-escaping. Is there a specific statement in the proposal that suggests that?
Regarding your additional questions:
Is there a practical use-case for asynchronously dispatching a non-escaping closure in place of an escaping closure?
This shouldn't be possible, so there wouldn't be a use-case for it :)
In the design proposal, it suggests that functional programming benefits from non-escaping (read: synchronous?) being the default. Is this true? Why?
The proposal says that functional programming would benefit from having less boilerplate (i.e. having to mark all parameters as #noescape). Since functional programming usually entails many functions-as-parameters that are predominantly non-escaping, this new default allows functional-style algorithms to have cleaner, less cluttered signatures and reduces typing the the #noescape boilerplate everywhere.
Is there any similarity between non-escaping closures and a promise in node.js?
No, promises are asynchronous and would be implemented in Swift using escaping closures, not non-escaping closures.
If I'm wrong about all of this, why not just call it #async instead of #escaping?
Because they are not exactly the same concept. An escaping closure may execute synchronously, but be saved off for execution at a later time. #async describes the nature of execution, but #escaping means only that the closure will be executed after the function it was passed to returns. When an escaping closure does execute, it might do so either synchronously or asynchronously at that time.

Blocks and messaging

The question here is more of an educational one. I began to think of this an hour ago while
flipping around a lego block (silly, I know).
A block is an object created on stack, from what I understand.
Let say A is an object, which means we can do:
[A message];
Based on that, if a block is an object, we could also do:
[block message];
Am I correct?
And when the runtime sees that, it would call:
objc_msgSend(block, #selector(message), nil);
So my question is, how can we send a block a message?
And if that is possible, I would imagine that it would also be possible to send a block a message with the arguments being blocks as well?
And, if we could call a block by doing:
block();
Does that mean we could even make a block as a message (SEL) as well, because blocks have the signature void (^)(void) which resembles that of a method?
Because if it would be possible, then the following would really surprise me:
objc_msgSend(block, #selector(block), block);
or:
objc_msgSend(block1, #selector(block2), block3);
I hope my imagination is not running a bit wild and that my understanding is not off here (correct me, if it is).
Blocks are objects only for the purposes of storage and referencing. By making them objects, blocks can be retain/release'd and can, therefore, be shoved into arrays or other collection classes. They also respond to copy.
That's about it. Even that a block starts on the stack is largely a compiler implementation detail.
When a block's code is invoked, that is not done through objc_msgSend(). If you were to read the source for the block runtime and the llvm compiler, then you'd find that:
a block is really a C structure that contains a description of the data that has been captured (so it can be cleaned up) and a pointer to a function -- to a chunk of code -- that is the executable portion of the block
the block function is a standard C function where the first argument must always be a reference to the block. The rest of the argument list is arbitrary and works just like any old C function or Objective-C method.
So, your manual calls to objc_msgSend() treat the block like any other random ObjC object and, thus, won't call the code in the block, nor, if it did (and there is SPI that can do this from a method... but, don't use it) could it pass an argument list that was fully controllable.
One aside, though of relevance.
imp_implementationWithBlock() takes a block reference and returns an IMP that can be plugged into an Objective-C class (see class_addMethod()) such that when the method is invoked, the block is called.
The implementation of imp_implementationWithBlock() takes advantage of the layout of the call site of an objective-c method vs. a block. A block is always:
blockFunc(blockRef, ...)
And an ObjC method is always:
methodFunc(selfRef, SEL, ...)
Because we want the imp_implementationWithBlock() block to always take the target object to the method as the first block parameter (i.e. the self), imp_implementationWithBlock() returns a trampoline function that when called (via objc_msgSend()):
- slides the self reference into the slot for the selector (i.e. arg 0 -> arg 1)
- finds the implementing block puts the pointer to that block into arg 0
- JMPs to the block's implementation pointer
The finds the implementing block bit is kinda interesting, but irrelevant to this question (hell, the imp_implementationWithBlock() is a bit irrelevant, too, but may be of interest).
Thanks for response. It's definitely an eye opener. The part about
blocks calling is not done thru objc_msgSend() tells me that it is
because blocks are not part of the normal object-hierachry (but coda's
mentioning of NSBlock seems to refute what I understand so far,
because NSBlock would make it part of the object-hierachy). Feel free
to take a stab at me, if my understanding is still off so far. I am
very interested in hearing more about the followings 1: the SPI and
the way (how) to call that method. 2: the underlying mechanisms of:
sliding the self reference into the slot. 3: finds the implementing
block and puts the pointer to that block into arg 0. If you have time
to share and write a bit more about those in detail, I am all ears; I
find this all very fascinating. Thanks very much in advance.
The blocks, themselves, are very much just a standard Objective-C object. A block instance contains a pointer to some executable code, any captured state, and some helpers used to copy said state from stack to heap (if requested) and cleanup the state on the block's destruction.
The block's executable code is not invoked like a method. A block has other methods -- retain, release, copy, etc... -- that can be invoked directly like any other method, but the executable code is not publicly one of those methods.
The SPI doesn't do anything special; it only works for blocks that take no arguments and it is nothing more than simply doing block().
If you want to know how the whole argument slide thing works (and how it enables tail calling through to the block), I'd suggest reading this or this. As well, the source for the blocks runtime, the objc runtime, and llvm are all available.
That includes the fun bit where the IMP grabs the block and shoves it into arg0.
Yes, blocks are objects. And yes, that means you can send messages to them.
But what message do you think a block responds to? We are not told of any messages that a block supports, other than the memory management messages retain, release, and copy. So if you send an arbitrary message to a block, chances are that it will throw a "does not recognize selector" exception (the same thing that would happen if you sent an arbitrary message to any object you don't know the interface of).
Invoking a block happens through a different mechanism than message sending, and is magic implemented by the compiler, and not exposed to the programmer otherwise.
Blocks and selectors are very different. (A selector is just an interned string, the string of the method name.) Blocks and IMPs (functions implementing methods) are somewhat similar. However, they are still different in that methods receive the receiver (self) and the selector called as special parameters, whereas blocks do not have them (the function implementing the block only receives the block itself as a hidden parameter, not accessible to the programmer).

objective c gcd - should a cancelled operation call a compeletion handler

Many long running async methods have completion handler blocks attached as input parameters to them
I'm not sure if the completion handler should be called if the operation was cancelled.
-(void)longRunningAsyncOperation:(Input *)input completionHandler:(Block)completionHandler
{
// long running code
// periodic checks for cancelation
if(_canceled)
{
// should completion handler still be called?
return;
}
// more long running code
// completed
completionHandler(someData);
}
I don't think there's necessarily one "right answer" here. You should just make it do whatever you need to do. One option, as #Fogmeister proposed in a comment is to make the completion routine take an argument indicating whether it was canceled or completed normally. It would seem advisable to have something called in all cases so that an interested party can know that the operation was canceled.
I've seen other APIs that take two different completion blocks -- a "success" block and a "failure" block. To my mind, a single block that takes arguments to indicate status seems like a more adaptable pattern.
If you don't call any completion block on cancelation then there is effectively "lost information"; absent some other mechanism, it's impossible for the outside world to know that the operation was canceled, so it seems like one of these patterns, be it an argument to the completion, or success/failure blocks, would be preferable to simply not calling anything.
#ipmcc is correct. There is generally no one right answer, but best practices generally dictates that you should always call the completion block and, if the completion block actually cares, pass it a success/cancelled flag. The reason this is a best practice is that some memory may have been allocated as a prelude to the cancelled operation and if you don't call the completion handler, you'll never have the opportunity to free it again.
I would say yes, it shall call the completion handler.
The rationale for this is, that one can view a completion handler as some form of return value.
So, not calling the completion handler is like not returning a value in a function which is declared to return something.

Resources