I've recently been trying to understand the importance of blocks in programming (Objective-C in particular). They're obviously used quite a lot in iOS/Cocoa APIs, so I'm trying to understand them.
Mostly, I still don't understand why you would use a block versus just creating a separate helper function. For example, if I create a block that implements some sorting function, wouldn't it be easier to create that function as a method of a helper class so all objects in the code could use it more easily?
Blocks are a nice alternative to callbacks or delegates, if for nothing else than improving code readability by keeping your business logic local to the calling code.
But they're so much more: highly useful for asynchronicity, and a necessity if you want to use GCD to improve performance.
Other than Apples official docs, I can highly recommend reading the excellent Practical Blocks by Mike Ash.
A nice feature of blocks is that they can be used wherever objects can be used, so you can e.g. store blocks in an array or dictionary. Another interesting thing is that you can pass blocks within an object or between objects as method arguments, e.g.:
- (void)processDataWithBlock:(void (^)(void))block
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations
The second method is even a UIView API. One could argue that function pointers would do here, but that would be more complicated, less flexible and incoherent. Also, blocks can access local variables and instance variables without passing them as arguments.
That's my 2 cents from blocks user point of view, but I'm none of an expert...
Related
I need to implement a bit of functionality that can be used from a few different places in an application. It's basically sending something over the network, but I don't need it to be attached to any particular view - I can communicate everything to the user by UIAlertViews.
What I would like to do is encapsulating the functionality in an object (?) that can maintain it's own state for a while and then disappear all by itself. I've read in several similar topics that it's generally not advised to have an object that retains and then releases itself, but on the other hand you have singletons which apart from the fact that they never get released, are very similar in nature. You don't need to keep reference to them just to use them properly. In my situation however I feel it woud be somewhat wasteful to create a singleton and then keep it alive for something that takes a few seconds to execute.
What I came up with is a static dictionary local to the class, that keeps unique references to the instances of the class, and then, when an instance is done with its task, it performs selector 'removeObjectForKey' after delay which removes the only existing reference and effectively kills the object. This way I keep only a dictionary in memory which for the most time is empty anyway.
The question is: are there any unexpected side effects of such a solution that I should be aware of and are there any other good patterns for described situation?
So basically instead of a persistent object of your own class, you've got a persistent object of type NSDictionary? How does that help matters? Is your object unusually large? If you are making your codebase more complicated for the sake of a few bytes, that's not a good tradeoff.
Especially now ARC is commonplace, this kind of trickery is usually not a good idea. Have you measured how much memory a singleton approach takes and found it to be a problem? Unless you have done this, use a singleton. It's simpler code, and all other things being equal, simpler code is far better.
Question
We're developing a custom EventEmitter inspired message system in Objective-C. For listeners to provide callbacks, should we require blocks or selectors and why?
Which would you rather use, as a developer consuming a third party library? Which seems most in line with Apple's trajectory, guidelines and practices?
Background
We're developing a brand new iOS SDK in Objective-C which other third parties will use to embed functionality into their app. A big part of our SDK will require the communication of events to listeners.
There are five patterns I know of for doing callbacks in Objective-C, three of which don't fit:
NSNotificationCenter - can't use because it doesn't guarantee the order observers will be notified and because there's no way for observers to prevent other observers from receiving the event (like stopPropagation() would in JavaScript).
Key-Value Observing - doesn't seem like a good architectural fit since what we really have is message passing, not always "state" bound.
Delegates and Data Sources - in our case, there usually will be many listeners, not a single one which could rightly be called the delegate.
And two of which that are contenders:
Selectors - under this model, callers provide a selector and a target which are collectively invoked to handle an event.
Blocks - introduced in iOS 4, blocks allow functionality to be passed around without being bound to an object like the observer/selector pattern.
This may seem like an esoteric opinion question, but I feel there is an objective "right" answer that I am simply too inexperienced in Objective-C to determine. If there's a better StackExchange site for this question, please help me by moving it there.
UPDATE #1 — April 2013
We chose blocks as the means of specifying callbacks for our event handlers. We're largely happy with this choice and don't plan to remove block-based listener support. It did have two notable drawbacks: memory management and design impedance.
Memory Management
Blocks are most easily used on the stack. Creating long-lived blocks by copying them onto the heap introduces interesting memory management issues.
Blocks which make calls to methods on the containing object implicitly boost self's reference count. Suppose you have a setter for the name property of your class, if you call name = #"foo" inside a block, the compiler treats this as [self setName:#"foo"] and retains self so that it won't be deallocated while the block is still around.
Implementing an EventEmitter means having long-lived blocks. To prevent the implicit retain, the user of the emitter needs to create a __block reference to self outside of the block, ex:
__block *YourClass this = self;
[emitter on:#"eventName" callBlock:...
[this setName:#"foo"];...
}];
The only problem with this approach is that this may be deallocated before the handler is invoked. So users must unregister their listeners when being deallocated.
Design Impedance
Experienced Objective-C developers expect to interact with libraries using familiar patterns. Delegates are a tremendously familiar pattern, and so canonical developers expect to use it.
Fortunately, the delegate pattern and block-based listeners are not mutually exclusive. Although our emitter must be able to be handle listeners from many places (having a single delegate won't work) we could still expose an interface which would allow developers to interact with the emitter as though their class was the delegate.
We haven't implemented this yet, but we probably will based on requests from users.
UPDATE #2 — October 2013
I'm no longer working on the project that spawned this question, having quite happily returned to my native land of JavaScript.
The smart developers who took over this project decided correctly to retire our custom block-based EventEmitter entirely.
The upcoming release has switched to ReactiveCocoa.
This gives them a higher level signaling pattern than our EventEmitter library previously afforded, and allows them to encapsulate state inside of signal handlers better than our block-based event handlers or class-level methods did.
Personally, I hate using delegates. Because of how objective-C is structured, It really clutters code up If I have to create a separate object / add a protocol just to be notified of one of your events, and I have to implement 5/6. For this reason, I prefer blocks.
While they (blocks) do have their disadvantages (e.x. memory management can be tricky). They are easily extendable, simple to implement, and just make sense in most situations.
While apple's design structures may use the sender-delegate method, this is only for backwards compatibility. More recent Apple APIs have been using blocks (e.x. CoreData), because they are the future of objective-c. While they can clutter code when used overboard, it also allows for simpler 'anonymous delegates', which is not possible in objective C.
In the end though, it really boils down to this:
Are you willing to abandon some older, more dated platforms in exchange for using blocks vs. a delegate? One major advantage of a delegate is that it is guaranteed to work in any version of the objc-runtime, whereas blocks are a more recent addition to the language.
As far as NSNotificationCenter/KVO is concerned, they are both useful, and have their purposes, but as a delegate, they are not intended to be used. Neither can send a result back to the sender, and for some situations, that is vital (-webView:shouldLoadRequest: for example).
I think the right thing to do is to implement both, use it as a client, and see what feels most natural. There are advantages to both approaches, and it really depends on the context and how you expect the SDK to be used.
The primary advantage of selectors is simple memory management--as long as the client registers and unregisters correctly, it doesn't need to worry about memory leaks. With blocks, memory management can get complex, depending on what the client does inside the block. It's also easier to unit test the callback method. Blocks can certainly be written to be testable, but it's not common practice from what I've seen.
The primary advantage of blocks is flexibility--the client can easily reference local variables without making them ivars.
So I think it just depends on the use case--there is no "objective right answer" to such a general design question.
Great writeup!
Coming from writing lots of JavaScript, event-driven programming feels way cleaner than having delegates back and forth, in my personal opinion.
Regarding the memory-managing aspect of listeners, my attempt at solving this (drawing heavily from Mike Ash's MAKVONotificationCenter), swizzles both the caller and emitter's dealloc implementation (as seen here) in order to safely remove listeners in both ways.
I'm not entirely sure how safe this approach is, but the idea is to try it 'til it breaks.
A thing about a library is, that you can only to some extend anticipate, how it will be used. so you need to provide a solution, that is as simple and open as possible — and familiar to the users.
For me all this fits best to delegation. Although you are right, that it can only have on listener (delegate), this means no limitation, as the user can write a class as delegate, that knows about all desired listeners and informs them. Of course you can provide a registering class. that will call the delegate methods on all registered objects.
Blocks are as good.
what you name selectors is called target/action and simple yet powerful.
KVO seems to be a not optimal solution for me as-well, as it would possibly weaken encapsulation, or lead to a wrog mental model of how using your library's classes.
NSNotifications are nice to inform about certain events, but the users should not be forced to use them, as they are quite informal. and your classes wont be able to know, if there is someone tuned-in.
some useful thoughts on API-Design: http://mattgemmell.com/2012/05/24/api-design/
Suppose I’m making an Objective-C class that represents a fraction, and want to create immutable and mutable versions.
Following the patterns in the Foundation framework, you might expect to see the method fractionByAddingFraction: in the immutable version and addFraction: in the mutable version.
The paradox I’m running into is how to only include the fraction-adding logic once between the two classes. It seems that the immutable fractionByAddingFraction: method needs to know about (and make use of) the mutable addFraction: method in order to avoid code duplication, and yet including the mutable methods in the implementation of the immutable class means they could conceivably be called on the immutable object, which defeats the point.
A brief explanation (or better still, a continuation of this simplified example) would be much appreciated!
Your approach is correct (if you really need a mutable subclass, which you should avoid unless you actually need it). I'm not quite clear where the confusion is coming in. You would most easily implement addFraction: using fractionByAddingFraction:. It would be a little inefficient, but that's the direction that would make the most sense. Something like:
- (void)addFraction:(Fraction *)anotherFraction {
Fraction *newFraction = [self fractionByAddingFraction:anotherFraction];
self.internalStuff = newFraction.internalStuff;
}
But typically you would probably handle this more efficiently with some private _GetInternalStuffByAddingInternalStuffs() function that both classes would use.
The primary implementations of Foundation’s collections cheat: there’s only one implementation, which is a subclass of NSMutableFoo, and it has a private mutability flag. This means client code can’t test whether a particular object is mutable or not, but that would never be a good idea anyway except perhaps for debugging and assertions.
In Objective-C, when I want to call a subroutine, I send a message to an object, like:
[self mySubroutine:myParameter];
There is a (negligible?) performance penalty, so I could just use a C-style function call:
mySubroutine(myParameter);
The implementation of the latter would then reside outside the class’s #implementation context.
Is this a no-no? Is it common? Is there a best-practice on this?
Note that those are not necessarily equivalent. Since -mySubroutine is an instance method, it probably needs to access a given instance. In that case, your mySubroutine() function should have another parameter for the instance, too.
In general, use a method. If you’re worried about performance,1 you can always get an IMP to the method and use it as a function instead of the standard Objective-C message dispatch infrastructure.
That said, some disadvantages of using functions:
They cannot be overridden by subclasses;
There’s no introspection (when using the runtime to obtain a list of methods declared by an Objective-C class, functions aren’t enumerated);
They cannot be used as accessors/mutators of declared properties;
They aren’t visible to Key-Value Coding;
They cannot be directly used for Objective-C message forwarding;
They cannot be directly used in the various cases where a Cocoa API expects a selector (e.g. when using NSTimer).
Some advantages of using functions:
They cannot be overridden by subclasses (if you want to prevent this);
There’s no introspection (if you want to prevent this);
They can be inlined;
They can have file scope (static), preventing code from other files from accessing them.
1When you’ve determined that the message dispatch infrastructure is actually a bottleneck. This does happen; for instance, some Apple audio examples do not use Objective-C for audio processing.
Edit: Based on OP’s comment, another advantage of functions is that they aren’t necessarily related to a class. If the computation of an approximate value for the sine of an angle doesn’t depend on an Objective-C instance, there’s no need to make it a method — a function is a better fit.
It might be worth using where you have static utility functions, such as in a maths library.
In general though, if you need methods that act on the state of an object, the C approach won't be much use, as you won't have implicit access to self, unless you explicitly pass it as a parameter.
You may also run into namespace issues. With the Objective-C different classes can share method names, with the c approach all your functions will need different signatures.
Personally I would always use objective-c methods, the performance difference will be negligible.
I'm trying to understand the concept of blocks. What I've read so far seems to be conceptually similar to anonymous functions in JavaScript. Is this correct?
Yes, for the largest part. Blocks are kind-of C functions treated kind-of like objects which can capture variables from the surrounding scope. Anonymous functions are equivalent to blocks, but certainly not identical due to the rather complicated behind-the-scene machinery of blocks.
For example, if you plan to use a block after/outside the function/method which defines the block isn't active anymore—it's the case if you set the block as a property somewhere or use in GCD (a multi-core operation queueing library), you need to copy it with Block_copy() (or [aBlock copy]). I won't go into the details, but this is certainly not something you do with JS (anonymous) functions. It has to do with the fact that block literals are allocated on the stack (and not somewhere in the code) and you need to copy it to the heap if you want it to persist.
It can get quite complicated (but rather beautiful in its design), but for most use cases it's rather easy and you can treat it like anonymous JS functions. ;-)
Yes. Blocks in Objective-C are closures.