What are the pros and cons of each of them?
Where should I use them specifically?
The rule of thumb here is how many clients would like to be notified of an event. If it's mainly one object (e.g. to dismiss a view or to act upon a button clicked, or to react to a failed download) then you should use the delegate model.
If the event you emit may be of an interest to many objects at once (e.g. screen rotated, memory usage, user login/logout), then you should use the NSNotificationCenter.
Their purposes are different:
Notification is used to broadcast messages to possibly several recipients unknown from the sender.
Delegation is used to send messages to a single known recipient acting on behalf of the sender.
Notifications are generally better for notifying the UI of changes the occur on other threads as well. Apple's documentation strongly discourages the use of delegates across threads where possible, both for stability and performance reasons. On the Mac, they suggest using Bindings, but since they don't exist on the iPhone, notifications are probably your next best bet.
Considering the performance is a good idea (delegation better for small number of notified objects, notification centre better for larger number of objects, or is it? run a profiler) but I think a more important factor since you are talking about Objective-C and less likely to be talking about the really high performance parts of your code base, which are likely to be written in C, is reducing compile-time dependencies between modules.
There is nothing to stop you having an array of delegates rather than a single delegate.
I might use NSNotificationCenter only for status of any network stack components I make and any custom device status monitoring interfaces. But for most coupling, not to do with global status of the app, I think it is clearer to use normal interface contracts in Objective-C in most cases and easier to folow for the people coming after you than to use NSNotificationCenter. In fact I have never used NotificationCenter for my own custom events and prefer to use delegates for ease of code comprehension by someone else reading my code.
And finally, of course with notifications to/from the standard API you don't have choice and must use whichever of the two methods Apple proscribe for a given event.
Notifications are better for decoupling UI components. It allows you to plug any view without any modification in your controllers or models. Definitely better for loosely-coupled design.
But for the performance between delegation and notification, you need to think about the frequency of the call.
Delegation might be better for more frequent events, notifications are better for less frequent events but more recipients. It's up to project what to pick.
An option in between those two is using the observer pattern, without NSNotificationCenter. Look at my Objective-C implementation here.
Related
Which design-pattern I should use in this case:
I have a rest API notification system.
I can notify by Email
notify by push;
notify by WhatsApp.
And I want to implement more technologies, and I do not want to modify the core, I want to add only modules to the system. For example, adding Telegram Messages, Twitter messages, or another email provider.
Any recommendation?
According to your problem statement, two different types of design patterns will be involved:
1) Strategy Pattern: It will define the notification strategy based on the contexts like email, push, whatsapp, etc.
3) Observer Pattern: It will perform the publisher and subscribers operation will the behavior of loose coupling. It will automatically notify to subcriber.
You can also integrate RabbitMq somewhere for queuing and on time pushing messages.
The case you explained is like strategy design pattern . You can use strategy design pattern and have an interface and a class for your each system that implement your interface. These are links that can help you :
tutsplus design ptterns
designpatternsphp
For a notification system I would suggest you using the Observer pattern. The message you receive should be inside your Subject. Subject should allow any number of Observers to attach. When a message is received, the subject should notify all the observers. Then Observers can read the state/message from the subject and act upon it. I am not pretty much clear about your usecase. But this would do the job.
To me seems a PUB-SUB model or a Observer pattern is best, extension in the form of subscriber registered to publisher works well as subscriber can have their own implementation details abstracting away from core notification service.
Strategy Pattern:
Define a family of algorithms (your types of notifications), encapsulate each one (each type of notification), and make them interchangeable (with a common abstraction). Strategy lets the algorithm vary independently from the clients that use it.
Capture the abstraction in an interface, bury implementation details in derived classes.
Each time you want to add different types of notification you will add new strategies (Twitter, Telegram, ecc)
observer - observable pattern suits for you. if u use any frameworks ( spring in java) built in futures - like event listener & publisher - this really reduces ur burden of implementations.
i hope u r already using frameworks - so research on event listener + publisher. it really solves ur problem ..not only enhancing support to multiple vendors.. it also supports - single - multi thread with less changes.
In any typical iPhone application, there will be model classes that are responsible for data loading/parsing. Upon completion of the data loading/parsing tasks, the affected controllers needed to be notified of the change in the model and update the view accordingly.
There are several listener/observer approaches for this in iPhone application development. What are the pros/cons and reasons for using each of the following approaches?
KVO
NSNotification
Delegate
Any other known approach
In my own experience:
Delegation:
PRO: use only when you have a single object to notify;
PRO: using an explicit protocol you can document clearly your intentions;
CON: can be the source of crashes and memory leaks if wrongly used (tip: don't retain delegates, assign them, and remember to deassign delegates when / if they are released!)
I wrote about memory management problems generated by delegation in this article on my blog:
http://akosma.com/2009/01/28/10-iphone-memory-management-tips/
NSNotification:
PRO: better when you have several objects to notify;
PRO: very flexible, leads to loosely-coupled classes;
CON: notifications are sent synchronously (so make sure your individual notification handlers only do very little)
CON: sometimes hard to document and maintain. Be sure to clearly explain in header docs what each notification means and when it is sent.
KVO:
Similar concerns about NSNotifications;
CON: even more obscure to document. Be sure to add more header docs or architectural tips on your comments to explain who's listening what. I personally wouldn't use KVO for data loading or parsing tasks.
Personally, when dealing with network-enabled apps talking to a remote web service, I use a singleton data loader class (wrapping ASIHTTPRequest and handling all the serialization and deserialization) which pops notifications when something occurs. This way I can have the app delegate handling connection errors on its own (popping up alerts and such if required), and each controller only cares about the responses it wants.
Of course, this approach depends on the application, but this general architecture might be a starting point for your own code.
Im using a large amount of very small web services in my app and I have been down a couple of roads that does not scale or work as desired.
The Design approach Im thinking about:
The task for the viewController is to ask for a set of data from a general webServicesClass, this task is started in a new NSThread -> this will instantiate an object which solely retrieves the xml and returns it to the webServicesClass -> the webServicesClass now instantiates an object which solely can Parse some XML coming from this particular web service. The Parser then returns a nice Entity object to the webServiceClass. The WebserviceClass now needs to inform the viewController about this data.
The viewController implements a webServiceClassDelegate and some delegate methods to see if the web service request went as planned. e.g. -(void)aWebserviceFailed and -(void)aWebserviceSuccess.
0.5 Since the WebserviceClass is running is a different NSThread, will it be a problem calling delegate methods on the main NSThread in the parent object?
1.0 I think this design is sound as it completely incapsulates the retrieval, parsing and returning of the Entity in different classes. But, I will have to write delegation methods and implement delegation protocols on each step of the way, for each different webservice. i.e. starting from the bottom, the WebserviceClass must implement delegation methods for both the object that retrieves the XML (start, fail, success), then for the object that parses the XML(start, fail, success) and the WebserviceClass must be able to delegate each of these responses to the viewController that again must implement delegation methods from the WebserviceClass(start, fail, success).
Is there a much simpler way to do this?
I have some design pattern experience, but not from languages that uses delegation so consistently as Objective C. In AS3 or Java I would have events that could bubble up through the objects and inform whoever was listening about changes. In all the Objective example code I have read I have only seen NSNotifications (which would be the equivalent of the AS3 or Java 'Event') used 0.1% of the times.
The Design I described will give me something that scales perfectly for many web services and gives me complete control over where a potential error/exception happens, but it seems to be a lot of code to obtain this loose coupling.
1.1 Or should I fully embrace the delegation approach and get to work:)
Thanks for any pointers or help given. Im not asking for source code or the likes, more a "this is considered best practice in Objective C in the every day situation you just described" :)
I'd recommend taking a look at ASIHttpRequest(obtainable here) and NSOperation + NSOperationQueue (docs here). I don't think you should run a long-lived thread to talk to your web service all the time, unless you absolutely need a constant connection.
Basically ASIHttpRequest and NSOperation both encapsulate all of the networking and threading stuff. Operations make multi-threading on the iPhone really nice. Essentially you create an operation (through a factory or whatnot for ease of use), pop it in a queue and do something with the result.
As for what you do with the result (this applies to your original scenario too and 0.5 and 1.1) what typically happens is your operation/thread will then call a didSucceedAtGettingWhatever or didFailWithError:(NSError*) method. Delegation is pretty much the defacto way of making requests on the phone. If there are multiple delegates, then you can just use subject-observer, like you would in Java.
As for 1.0, ultimately no. What we typically do is we have an OperationDelegate and OperationTypes. Based upon which OperationType succeeded or completed, we have different logic. It's not the greatest and there are a ton of different ways of doing this, but you will have to have separate logic for separate events regardless of what you do. Whether or not that's in one method or many methods is up to you.
I am sold on KVO but if used in the obvious way it is synchronous. I would like to use it in a situation where I am firing off many KVO messages in rapid succession and it is causing my app to grind to a halt as the KVO messages are handled. Can someone suggest an approach - perhaps using NSOperation or NSThread - that will work here?
My goal is to retain the decoupled, flexibility of KVO if possible.
KVO is inherently single threaded in that the KVO notifications will be delivered on the same thread as the change.
Of course, UIKit and Cocoa both really only want you to be diddling UI elements on the main thread.
Thus, if you are doing asynchronous operations, you are most likely using threads and, if so, already have a synchronization issue in that you need to get the notifs from some thread to the main thread.
And therein lies the key. Instead of blindly forwarding each change notification as it comes in, you can coalesce the change notifications before passing them on to the main thread.
There are a variety of means via which you can do this. The specific solution is going to be quite unique to your application, most likely.
Personally, I try to avoid coalesce-and-forward of fine grained operations. I find it far simpler to tell the main thread that a particular sub-graph of objects have changed. More likely than not, the drawing code that will then make the changes visible to the user is going to need to redraw related state and, thus, related changes will be automatically reflected.
The key, as you have surmised, is to throttle the notifications so you don't bog down app responsiveness (or destroy the devices battery life).
Use the Receptionist Pattern as recommended by Apple https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ReceptionistPattern/ReceptionistPattern.html
Check out NSNotification. It's not quite the same thing, but you can fire off notifications on background threads (with a little bit of research and work). You can maintain the nice decoupling and fire-and-forget behavior.
Just to give background for my situation, I have a manager singleton that pulls data from a webserver and provides access to the downloaded data. I have several types of views that will consume this data, but only one view at any time will need to receive events.
I was just wondering what people prefer to use when they need to get events from a singleton. Do you use NSNotificationCenter, Target/Action, or delegate?
Thanks for any help.
Are you really, really sure only one view needs to receive events? For instance, you don't have a master view that would need access to the same update that a subview was notified about?
If you truly have only one view controller needing updates at a time ever, I might use a delegate approach. Here's something to consider - what happens if you are in the middle of receiving an update and the user change screens... is that OK? would you cancel the request?
Anything more than one, or if that in-flight changing delegate scenario has issues, then you may well be better off with a notification that anyone can hook into. It's best to keep the notification light with some kind of reference to the change and have the receiver have to look up the altered data.
If there are going to be a large number of events, then you want to stay away from NSNotifications.
For the least amount of overhead I would go with the delegate pattern, although I don't think that target/action has much more overhead than delegates.
Try your favorite way and if there is a problem profile or try a different approach.
I usually start with the easiest to get implemented. For example I once tried to use notifications for some interface code I had written years ago but with 30-60 updates/second the whole interface bogged down unacceptably so I went with delegates which fixed the problem.