My question is very straight forward: is the delegate design pattern in iOS truly multithreaded? Meaning is there actual parallel execution going on or is it still all running on the main thread?
It depends if you call the delegate methods on a different thread or not. In general, delegate methods are called on the same thread after a certain event. In short terms, threading has nothing to do with delegation and from my experience Apple always posts the delegate callbacks methods to the main thread (however, you can choose not to, but things can become nasty if you do).
Delegation has nothing to do with threading. Delegation is about allowing one object to make decisions on behalf of another. It is normally done in a single-threaded manner, since there's little to be gained from spawning a thread every time you want to ask a delegate something and it would complicate the design considerably.
Related
When I first read about NSZone and what it was, I got really excited about the prospect of using zones to isolate threads' memory spaces such that I could effectively kill a thread and dealloc its zone. But it seems NSZone can't really be used for this purpose after all.
So I'm wondering if there's any way to isolate a thread in Objective-C to a particular block of memory that can be killed and dealloced safely?
Failing that, are there ways to spawn child processes (that surely do have their own memory spaces) in Objective-C, similar to how Chrome does things?
Inter-process communication is a subject that is far too challenging for what you're trying to implement. So long as you're just looking for a representation of some work that you can cancel and deallocate, a subclass of NSThread is perfect. By overriding -main, you can have all the benefits of an NSOperation (not caring exactly which thread work occurs on, abstraction from actual threading, encapsulation, etc.), but in a more concrete and cancelable form.
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/
When writing the usual view controller code, can I assume that this will only be called from a single event-loop thread? What kind of classes do I need to make thread-safe? What are the usual situations where multiple threads are involved?
The concurrency programming guide is good. Here are some super important things to keep in mind.
– You should only update UI from the main thread. This can get you in subtle ways...
– NSNotifications will be received in the thread from which they are fired. So if you launch a thread and subscribe to a NSNotification to trigger a UI action, you should check what thread you're on when you get it. If it's not on the main thread use NSObject's performSelectorOnMainThread: withObject:waitUntilDone: to get it on the main thread.
– If you're doing some drawing into a non-ui context, I believe core graphics is now thread safe. (I believe CATiledLayer does some clever things because of this)
– Generally for view controllers, the only event loop you should think about is the one on the main thread. Think twice before making your own event loop on another thread.
If you are writing normal UIViewController code, you don't need to worry about thread-safety in iOS. In iOS, any message about UI should be running on the main thread.
If you don't perform some message in background by you self, normally, you don't have to worry about thread, in most situations, it will always be on the main thread.
P.S. Some Frameworks like Game Kit will some times perform messages in background, but it's not about UI and the document from Apple will warn you to make sure if the message is running on main thread.
The Concurrency Programming Guide can be helpful.
Most iPhone code examples use the nonatmoc attribute in their properties. Even those that involve [NSThread detachNewThreadSelector:....]. However, is this really an issue if you are not accessing those properties on the separate thread?
If that is the case, how can you be sure nonatomic properties won't be accessed on this different in the future, at which point you may forget those properties are set as nonatomic. This can create difficult bugs.
Besides setting all properties to atomic, which can be impractical in a large app and may introduce new bugs, what is the best approach in this case?
Please note these these questions are specifically for iOS and not Mac in general.
First,know that atomicity by itself does not insure thread safety for your class, it simply generates accessors that will set and get your properties in a thread safe way. This is a subtle distinction. To create thread safe code, you will very likely need to do much more than simply use atomic accessors.
Second, another key point to know is that your accessors can be called from background or foreground threads safely regardless of atomicity. The key here is that they must never be called from two threads simultaneously. Nor can you call the setter from one thread while simultaneously calling the getter from another, etc. How you prevent that simultaneous access depends on what tools you use.
That said, to answer your question, you can't know for sure that your accessors won't be accessed on another thread in the future. This is why thread safety is hard, and a lot of code isn't thread safe. In general, if youre making a framework or library, yeah, you can try to make your code thread safe for the purposes of "defensive programming", or you can leave it non-thread safe. The atomicity of your properties is only a small part of that. Whichever you choose, though, be sure to document it so users of your library don't have to wonder.
SO is telling me this question is subjective and likely to be closed. It is indeed subjective, because I'm asking for the opinion of experienced Objective-C developers. Should I post this somewhere else? Please advise.
Fairly new to Objective-C, though fairly confident in the concept of writing OOP code, I've been struggling with the NSNotification vs Delegate dilemma from the start. I've posted a few questions about that subject alone. I do get the gist, I think. Notifications are broadcasted globally, so shouldn't be used for notifying closely related objects. Delegates exist to hand over tasks to other object, that act on behalf of the delegated object. While this can be used for closely related objects, I find the workflow to be verbose (new class, new protocol, etc), and the word "delegation" alone makes me think of armies and bosses and in general makes me feel uneasy.
Where I come from (AS3) there are things called Events. They're halfway between delegates and NSNotifications and pretty much ruled the world of flash notifying, until fairly recently, a Mr. Robert Penner came along and expressed his dissatisfaction with events. He therefore wrote a library that is now widely used in the AS3 community, called Signals. Inspired by C# events and Signals/Slots in Qt, these signals are actually properties of objects, that you access from the outside and add listeners to. There's much more you can do with a signal, but at it's core, that's it.
Because the concept is so humble, I gave it a go and wrote my own signal class in Objective-C. I've gisted Signal.h/.m here.
A way to use this for notifying class A of an event in class B could look like this:
// In class b, assign a Signal instance to a retained property:
self.awesomeThingHappened = [[[Signal alloc] init] autorelease];
// In class a, owner of class b, listen to the signal:
[b.awesomeThingHappened add:self withSelector:#selector(reactToAwesomeThing)];
// And when something actually happens, you dispatch the signal in class b:
[self.awesomeThingHappened dispatch];
// You might even pass along a userInfo dictionary, your selector should match:
[self.awesomeThingHappened dispatchWithUserInfo:userInfo];
I hope it adheres to the right memory management rules, but when the signal deallocs, it should automatically remove all listeners and pass away silently. A signal like this isn't supposed to be a generic replacement of notification and delegation, but there are lot's of close counter situations where I feel a Signal is cleaner than the other two.
My question for stackoverflow is what do you think of a solution like this? Would you instantly erase this from your project if one of your interns puts it in? Would you fire your employee if he already finished his internship? Or is there maybe already something similar yet much grander out there that you'd use instead?
Thanks for your time, EP.
EDIT: Let me give a concrete example of how I used this in an iOS project.
Consider this scenario of four object types with nested ownership. There's a view controller owning a window manager, owning several windows, each owning a view with controls, among which a close button. There's probably a design flaw in here, but that's not the point of the example :P
Now when the close button is tapped, a gesture recognizer fires the first selector in the window object. This needs to notify the window manager that it's closing. The window manager may then decide whether another window appears, or whether the windows stay hidden alltogether, at which point the view controller needs to get a bump to enable scrolling on the main view.
The notifications from window to window manager, and from window manager to view controller are the ones I've now implemented with Signals. This might have been a case of delegation, but for just a 'close' action, it seemed so verbose to create two delegate protocols. On the other hand, because the coupling of these objects is very well defined, it also didn't seem like a case for NSNotifications. There's also not really a value change that I could observe with KVO, because it's just a button tap. Listening to some kind of 'hidden' state would only make me have to reset that flag when reopening a window, which makes it harder to understand and a little error prone.
Alright, after marinating the answers and comments for a bit, I think I have come to a conclusion that the Signal class I borrowed from AS3, has very little reason for existence in Objective-C/Cocoa. There are several patterns in Cocoa that cover the ranges of use that I was thinking of covering with the Signal class. This might seem very trivial to more experienced Cocoa developers, but it for me it was hard to get the spectrum complete.
I've tried to put it down fairly concisely, but please correct me if I have them wrong.
Target-Action
Used only for notifying your application of user interaction (touches, mostly). From what I've seen and read, there's no way to 'borrow' the target-action system for your own use
KVO (key value observing)
Very useful for receiving notifications when values change in accessible objects. Not so useful for notifying specific events that have no value attached to them, like timer events or interface followup events.
NSNotification
Very useful for receiving notifications when values change or other events happen in less-accessible objects. Due to the broadcast nature of the notification center, this is less suitable for cases where objects have a direct reference to another.
Delegation
Takes the most lines of code compared to the other three, but is also most suitable when the other three are not. Use this one when one object should be notified of specific events in the other. Delegates should not be abused for just accessing methods of the owner object. Stick to methods like 'should', 'will' and 'did'.
Signal
It was a fun experiment, but I mostly used this for classic delegation situations. I also used it to circumvent linked delegates (c delegate of b, b delegate of a, where a starts the event that should make it to c) without wanting to resort to NSNotification.
I still think there should be a more elegant solution for this edge case, but for now I'll
just stick to the existing frameworks. If anyone has a correction or another notification concept, please let me know. Thanks for your help!
It's an interesting idea, but I guess I don't see what makes it dramatically different from Cocoa's notification center. Compare and contrast:
self.awesomeThingHappened = [[[Signal alloc] init] autorelease]; // Your signals library
// Cocoa notifications (no equivalent code)
[b.awesomeThingHappened add:self withSelector:#selector(reactToAwesomeThing)]; // Your signals library
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reactToAwesomeThing:)
name:#"AwesomeThingHappened"
object:n]; // Cocoa notifications
[self.awesomeThingHappened dispatch]; // Your signals library
[[NSNotificationCenter defaultCenter] postNotificationName:#"AwesomeThingHappened"
object:self]; // Cocoa notifications
[self.awesomeThingHappened dispatchWithUserInfo:userInfo]; // Your signals library
[[NSNotificationCenter defaultCenter] postNotificationName:#"AwesomeThingHappened"
object:self
userInfo:userInfo]; // Cocoa notifications
So, okay. I don't think you're trying to say that, line-for-line, a Signals library for Cocoa is different; rather, the argument goes that it terms of coupling, it isn't as tight as delegates, but not as loose as notifications. To that end, I guess I wonder how necessary it is? I guess I can see somewhat of a need to say "this object 'A' relies heavily on 'B', but doesn't need to be coupled all that closely", but to be honest, that seems like somewhat rare situation.
At any rate, NSNotificationCenter and its ilk, as well as delegates, are pretty standard in Cocoa apps. I always use the rule of thumb that if you deviate from a standard, even a de facto standard, you should have a good reason. If you have a good reason for using neither NSNotificationCenter nor delegates, then you might have a good reason to use this Signals setup. (And as an aside, I'm hesitant to associate notifications and delegates -- they each have a role and exist for different reasons.)
It's hard to say more without a specific use case. I'm inclined to say, "Hey, it looks cool in a geeky way, but it looks like it fills a role already served by notifications." Do you have any specific use cases you could cite?
What do you think of a solution like this?
I don't really see what the benefit is. To me, it seems like a combination of target/action+notifications (you can have multiple target/actions for a single notification event, but the t/a pair is registered with the object itself as opposed to a global notification center). In fact, it's more like key-value-observing that way, except that KVO is limited to observable properties.
Would you instantly erase this from your project if one of your interns puts it in?
No. It's not bad code. In fact, it seems kinda neat. But I just don't see an obvious benefit to it.
Would you fire your employee if he already finished his internship?
Of course not. You don't fire people for writing good code.
Is there maybe already something similar yet much grander out there that you'd use instead?
If you really wanted to make this neat, change the API to use blocks instead. Then you could do:
[object dispatchOnAwesomeThingHappened:^{
NSLog(#"holy cow, something awesome just happened!");
}];
Again, however, you'd be limited to reacting to stuff that the objects explicitly "dispatch". It would be much neater if you could attach stuff to immediately before and/or after any arbitrary method call. If you're interested in that, then I'd check out Aspect Objective-C on github.
I think that there is a gap between NSNotifications and Delegates. And KVO has the worst API in all of Cocoa.
As for NSNotificationCenter here are some of its problems:
it's prone to typos
it's hard to track observers of a given object, therefore hard to debug
it's very verbose
you can only pass notification data in a dictionary, which means you can't use weak references, or structs unless you wrap them. (see: very verbose)
doesn't play nice with GCD: limited support for queues (only blocks)
So there is definitely a need for something better.
I created my own observable class which I use on every project. Another alternative is to use ReactiveCocoa's RACSignal.