UIViewController dismissViewControllerAnimated completion argument type syntax - objective-c

The void (^)(void) syntax of the 'completion' argument type implemented by the UIViewController method:
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion
has piqued my curiosity and I have been unable to find any documentation for it. Please could someone help explain its purpose/meaning?
Many thanks in advance.

Here's the discussion of blocks from my book:
http://www.apeth.com/iOSBook/ch03.html#_blocks
There's an example there, but here's an example that's closer to the sort of thing you're asking about:
[self transitionFromViewController:fromvc
toViewController:tovc
duration:0.4
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:nil
completion:^(BOOL done){
[tovc didMoveToParentViewController:self];
[fromvc removeFromParentViewController];
}];
The completion block takes one parameter, a BOOL called "done", but this is not used by its code. The idea is that the animation is performed and then the code in the completion block is run.
It's very important to be comfortable with blocks because they are the way of the future. For example, view animation in iOS 4 uses them, as explained in the "Block Based View Animation" section of my book (read first about the old way, then read about the new iOS 4 way):
http://www.apeth.com/iOSBook/ch17.html#_view_animation
In iOS 5 blocks are even more important; there are more and more situations where they are not optional.
Also blocks are the way to use GCD (grand central dispatch), which is far and away the best way to do multi-threading.

That would be for a completion block. A block is a snippet of code that may be submitted as an argument (often seen, as here, for completion handling) to an API. There are many features of blocks, including the ability to reference memory and maintain state.
See documentation on this increasingly popular feature of Obj-C:
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html
Blocks provide what might be considered callback behavior (typically achieved with delegation or notification), but they allow the programmer to include the logic of the completion behavior in the same context as the initiating action, making the code more expressive and conveying the complete progression of intended behavior concisely.

Related

Sending code to the background, waiting, then going back to the main thread without blocking?

A common pattern in Objective C is to run a bit of code in a background thread, then go back to the main thread to make UI adjustments. If the code starts in the main thread, I'd attack this with a pattern like so:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self someBackgroundTask];
dispatch_async(dispatch_get_main_queue(), ^{
[self someUITask];
});
});
However, this seems like a really clunky way to do it, not in the least because it creates two levels of nesting that feeling unnecessary. Is there a better way to do this? Note that the UI code is considered in this instance to be relying on the background task completing, so it can't just be dropped after the first dispatch.
Just move all the threading stuff into someBackgroundTask:
[self someBackgroundTaskWithCompletion:^{
[self someUITask];
}];
Then do your dispatch_async() stuff inside the background task method.
Conceptually, you need to run code on two different threads. All UI operations must run on the main thread, and your blocking operation needs to run on a background thread. At the absolute minimum this would require two lines of code.
GCD makes this fairly simple as you mentioned; I'm not sure any language would have a better way to handle this core issue. Sure, the block syntax is bad (http://fuckingblocksyntax.com); but the core fundamentals are pretty solid.
If the nesting bothers you, try moving all that UI code to a different method, and calling that method from your second nested block. You could even create a method that accepts a 'backgroundWork' selector/block and a 'foregroundWork' selector/block. However - I'd argue that the typical UI work you'd perform in such a case would be very minimal, making the extra nesting a minor inconvenience rather than an actual problem.
As far as asynchronous blocks of code that are inter-dependent, check out PromiseKit or even Sequencer; both are good options for supplementing one of Objective C's primary weakness (sequentially performed multi-threaded operations).
I haven't used it myself, but I understand that Facebook/Parse have also released another solution called BFTask, part of the Bolts framework: https://github.com/BoltsFramework/Bolts-iOS
(Or just use C#)

How does KVC deal with speed and errors?

I've been reading about KVC and Cocoa Scripting, and how properties can be used for this. I have a model class in mind, but the element/property data has to be obtained from the Internet. But the design of properties and KVC looks like it assumes fast & in-memory retrieval, while network calls can be slow and/or error-prone. How can these be reconciled?
For speed, do we just say "screw it" and post a waiting icon? (Of course, we should keep things multi-threaded so the UI doesn't stop while we wait.)
If your property is supposed to be always available, we could set it to nil if the resource call gets an error. But we would have no way to get the specifics. Worse would be a property that supports "missing values," then nil would represent that and we would have no spare state to use for errors.
Although Apple-events support error handling, I couldn't use it because between my potentially error-generating model calls and the Apple event, the KVC layer would drop the error to the floor (of oblivion). The Scripting Bridge API saw this problem, since its designers added a secret protocol to handle errors.
Am I wrong? Is there a way to handle errors with KVC-based designs?
Addendum
I forgot to mention exceptions. Objective-C now supports them, but the little I read about them implies that they're meant for catastrophic "instead of straight crashing" use, not for regular error handling like in C++. Except for that, they could've been useful here....
I think I understand what you're asking now. I would say using KVC (or property getters) is not a good way to accomplish what you're trying to do. If the code gets called on the main thread, you will then block that thread. which you don't want to do. As you have discovered you'll also have a hard time returning other state information such as errors.
Instead, you should use block syntax to create an asynchronous method that operates on a background queue. Here is a basic template for what this might look like:
// called from main thread
- (void) fetchDataInBackgroundWithCompletionHandler:(void (^)(id responseData, NSError *error))handler
{
// perform in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^()
{
// perform your background operation here
// call completion block on main thread
dispatch_async(dispatch_get_main_queue(), ^{
if(// whatever your error case is)
{
handler(nil, error);
}
else // success
{
handler(responseData, nil);
}
});
});
}
This also gives you the benefit of being able to pass in as many other parameters are you want as well as return as many values as you want in the completion block.
Some very good examples of this pattern can be seen in AFNetworking, which is one of the more popular networking libraries written for iOS. All of the calls in the library can be made from the main queue and will return on the main queue asycnhronously while performing all networking in the background.

C/ObjC: How to unit-test blocks?

According to this Stackoverflow post: Selectors or Blocks for callbacks in an Objective-C library ,
blocks seem to be the future of ObjC. However, much like anonymous functions, blocks feel more like "drafting" an implementation. Also, due to its "embedded" nature, I fear that overusing them will break modularity in the sense of unit-testing or "testable" OOP.
I couldn't find much guideline on how to test blocks and how to coordinate tests for blocks and regular methods. Are there good resources for this topic?
I created 3 macros that wait for the block to be executed in a unit test so the assertions can be made inside the block.
#define TestNeedsToWaitForBlock() __block BOOL blockFinished = NO
#define BlockFinished() blockFinished = YES
#define WaitForBlock() while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !blockFinished)
Example:
- (void)testWaitForBlock {
TestNeedsToWaitForBlock();
[target selectorWithInlineBlock:^(id obj) {
// assertions
BlockFinished();
}];
WaitForBlock();
}
Not sure if you've already tried it, but I use Kiwi for unit testing my iOS applications. Its not amazingly documented but it can be used for testing blocks.
https://github.com/allending/Kiwi
Take a look at the 'capturing arguments' under 'mocks and stubs' on their wiki. You can use this to capture a block thats being passed. This is really useful for code thats asynchronous - you can call the method you want to test, capture some completion block and then immediately execute the block synchronously, making your asynchronous code effectively synchronous.
In reference to blocks feeling like drafting an implementation - they don't have to be like that. I define blocks as a would a method, not inline. In fact I often write a method to return the block, making the code clean and easily testable.
Not sure if thats what you were looking for.
- (void)testWaitForBlock {
[target selectorWithInlineBlock:^(id obj) {
// assertions
BlockFinished();
}];
//use this to keep runloop is alive ,you can do anything.
NSDate * date = [NSDate dateWithTimeIntervalSinceNow:10];
[[NSRunLoop currentRunLoop]runUntilDate:date];
}

What's the difference between "performSelector:withObject:afterDelay:" where delay is 0, and just calling the selector?

I'm working on an iPad project that uses a third-party SDK, and have been reading through the SDK code to learn about it and objective-c. I came across the following line in an asynchronous callback:
[self performSelector:#selector(doSomething) withObject:nil afterDelay:0];
I've read through the documentation on that selector. The relevant line appears to be the following:
Specifying a delay of 0 does not necessarily cause the selector to be performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible.
I can't determine why one should write [self performSelector:#selector(doSomething) withObject:nil afterDelay:0], as opposed to merely writing [self doSomething]. It seems to me that a delay of zero means that the call should be made immediately. Clearly I'm missing something, it's unlikely that the framework author chose this approach at random. Other StackOverflow answers don't shed any light on this either. Is the "performSelector" selector being used because the doSomething selector itself is asynchronous, and the call is being made in an asynchronous callback?
I did find another link suggesting the following:
It's interesting to note that using performSelector with afterDelay will also let the warning [viz, a compiler warning] go away: ...
[self performSelector:aSelector withObject:nil afterDelay:0.0];
So did the author use this code to suppress a compiler warning only? If that's the case, then it's probably preferable to suppress the warnings through clang push/pops, as suggested in this thread.
If anyone has a cogent explanation as to why the author used the ...afterDelay method, I'd be grateful. Thanks.
Edit Oct 22, 2012: I don't believe that the sole answer given here by #rmaddy is wholly applicable to my situation, but it's still a good answer, so I'll accept it. I'll keep tabs on this question and come back if I find anything new. Thanks. J.Z.
One possible use of something like:
[self performSelector:#selector(doSomething) withObject:nil afterDelay:0];
is to allow the current runloop to complete before 'doSomething' is called. In other words, the current call stack can be completed (the current method returns) before 'doSomething' is called. Often this is used to give the UI a chance to update.
It's hard to know the author's true intent though without more context but this is a common use.

Is there a simple way (in Cocoa/iOS) to queue a method call to run once in the next run loop?

UIView has a setNeedsDisplay method that one can call several times within the same event loop, safe in the knowledge that the redrawing work will happen soon, and only the once.
Is there a generic mechanism for this sort of behaviour Cocoa? A way of of saying, "Queue a selector as many times as you like, when it's time, the selector will run once & clear the queue."
I know I could do this with some kind of state tracking in my target, or with an NSOperationQueue. I'm just wondering if there's a lightweight approach I've missed.
(Of course, the answer may be, "No".)
setNeedsDisplay is not a good example of what you're describing, since it actually does run every time you call it. It just sets a flag. But the question is good.
One solution is to use NSNotificationQueue with NSNotificationCoalescingOnName.
Another solution is to build a trampoline to do the coalescing yourself. I don't have a really good blog reference for trampolines, but here's an example of one (LSTrampoline). It's not that hard to build this if you want to coalesce the messages over a period of time. I once built a trampoline with a forwardInvocation: similar to this:
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation setTarget:self.target];
[invocation retainArguments];
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.timeout invocation:invocation repeats:NO];
}
This actually coalesces all messages to the object over the time period (not just matching messages). That's all I needed for the particular problem. But you could expand on this to keep track of which selectors are being coalesced, and check your invocations to see if they match "sufficiently."
To get this to run on the next event loop, just set timeout to 0.
I keep meaning to blog about trampolines. Required shilling: My upcoming book covers trampolines in Chapter 4 and Chapter 20.
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:#selector(doTheThing:)
object:someObject];
[self performSelector:#selector(doTheThing:)
withObject:someObject
afterDelay:0];
This is not exactly how UIView is doing it because setNeedsDisplay simply sets a flag and the internal UIView mechanism makes sure to call drawRect: after setting up the drawing environment, but this is a generic way and doesn't require any special state tracking in your class.