This is just a theoretical question. It was born from a real problem in my app, but I re-designed the problem out of the application. But the question remains:
If in my app delegate I write my singleton object to disk upon applicationWillTerminate: but also use NSNotificationCenter to call updateSingletonData upon UIApplicationWillTerminateNotification in some view controller, which will happen first? Will my data be written to the singleton, then the singleton be written to disk, then the app terminates? Or will the reverse happen, with the singleton being serialized and then the singleton updated (worse), or will the app just terminate after a certain amount of time if the serialization takes too long (much worse!)?
I guess this shows my lack of understanding of the guts of Springboard... thanks to anyone who can shed some light here.
A couple of things to note here:
Only Apple know the order these will happen in, as they wrote the code that does it.
You shouldn't care about the order these will happen in. If you do care, then you've designed your code badly.
In reality, you could go and check what order the happen in - for your particular device, for your particular iOS version, etc.
But really, you shouldn't care what order they happen in. From the sounds of it, you should be either firing off to the view controller to write the data before saving in applicationWillTerminate:, or letting the view controller handle saving after it's written its data.
This question is old and the response by #mattjgalloway is correct in terms of code quality but, for the sake of the knowledge, I just saw in the docs that the notification is posted after the UIApplicationDelegate method is called (emphasis mine):
After calling this method, the app also posts a UIApplicationWillTerminate notification to give interested objects a chance to respond to the transition.
https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate
Related
Check the GitHub project for this article.
A notification is sent by prepareForReuse method of the custom cell(JKCallbacksTableViewCell class) to the table(RootViewController class) which is observed by the tableViewCellIsPreparingForReuse method. This method resets the association key and the imageview of the cell.
So, why does author preferred to send it through a notification instead of resetting them after getting a non-nil cell from dequeueReusableCellWithIdentifier method of the table?
According to the documentation of UITableViewCell, prepareForReuse is called just before dequeueReusableCellWithIdentifier.
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:.
I have tested it that when dequeueReusableCellWithIdentifier returns a non-nill value it's coupled with a call to prepareForReuse.
Author commented in the JKCallbacksTableViewCell.h about application logic separation but i think that is a kind of overkill; optimizing performance with async dispatch but sending those slow notifications to reset some properties... Or am i missing something about GCD?
Most programming problems have a near-infinite number of solutions. I didn’t have any particular reason to choose notifications other than the fact that they’re loosely coupled.
Regarding your comment about the speed of the notification: the thing that makes the app slow is loading the images, so we’re trying to optimize that. Notifications aren’t slow enough to make a difference in the use of the app otherwise, so to use something else for pure performance reasons is unwarranted here.
That said, it’s in GitHub, so feel free to send a pull request that doesn’t use notifications. If I like it better, I’ll use it.
I just read a couple of tutorials regarding KVO, but I have not yet discovered the reason of its existence. Isn't NSNotificationCenter an easier way to observe objects?
I am new to Stackoverflow, so just tell me if there is something wrong in the way I am asking this question!
Notifications and KVO serve similar functions, but with different trade-offs.
Notifications are easy to understand. KVO is... challenging... to understand (at least to understand how to use it well).
Notifications require modification to the observed code. The observed must explicitly generate every notification it offers. KVO is transparent to the observed code as long as the observed code conforms to KVC (which it should anyway).
Notifications have overhead even if you don't use them. Every time the observed code posts a notification, it must be checked against every observation in the system, even if no one is observing that object (even if no one is observing anything). This can be very non-trivial if there are more than a few hundred observations in the system. It can be a serious problem if there are a few thousand. KVO has zero overhead for any object that is not actually observed.
In general, I discourage KVO because of some specific implementation problems that I believe make it hard to use correctly. It's difficult to observe an object that your superclass also observes without special knowledge of your superclass. Its heavy reliance of string literals make small typos hard to catch at compile time. In general, I find code that relies heavily on it becomes complex and hard to read, and begins to pick up spooky-action-at-a-distance bugs. NSNotification code tends to be more straightforward and you can see what's happening. Random code doesn't just run when you didn't expect it.
All that said, KVO is an important feature and developers need to understand it. More and more low-level objects rely on it because of it's zero-overhead advantages. But for new developers, I typically recommend that they rely more on notification rather than KVO.
There is a third way. You can keep a list of listeners, and send them messages when things change, just like delegate methods. Some people call these "multicast delegates" but "listeners" is more correct here because they don't modify the object's behavior as a delegate does. Doing it this way can be dramatically faster than NSNotification if you need a lot of observation in a system, without adding the complexity of KVO.
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.
Part of me thinks I understand the NSNotification concept. It's a centralized broadcast system with string based notifications. Post on one side, observe on one or multiple other sides and act accordingly. Another part of me though, the part that has to write the code, gets confused every time I need a notification. What piece of code goes into which header/implementation, what files actually do the observing and how do I keep it from becoming a mess? Time to straighten it out, will you help me verify these assumptions? I'm fairly confident up to number 4, but number 5 hits the confusion jackpot.
NSNotifications are created with help from the [NSNotification defaultCenter], one does not alloc/init a NSNotification. Correct?
The object performing the postNofification feat always passes self into the posting code: [[NSNotificationCenter defaultCenter] postNotificationName:#"note name" object:self]. Correct?
Event bubbling exists in other languages, but not in Objective-C with NSNotification. You don't pass along notifications, you make the notification name specific enough for the global broadcast. Correct?
If you still want to pass along a notification posted by object A, you observe it in B, handle it and post a new, more specific notification for object C to observe. Eg. #"MenuItemTapped" from A to B, and #"NavigateTo" from B to C. Correct?
The name of a notification is a NSString. Because both the poster and the observer want to avoid typos, we store the NSString constant in a [extern const|define|class method|none of the above]. Could you help me pick one?
One attempt was to create something like a NotificationNames.h file, which would contain all the extern NSString *const NOTE_NAME declarations. Yet that undermines the portability of a notification.
Another attempt was to subclass NSNotification (with an XCode template to keep the creation fast), but because this concept is taken from subclassing the Event-class in AS3, it seemed very un-objective-c-ish. There's also the weirdness that you can't call [super init] on a NSNotification, so things started to get out of hand.
My troubles with this one arise from the cumbersome #import statements. How to minimize typo's, yet keep the constants/defines portable?
You've mostly got it. Your numbers 1-3 are generally correct.
You shouldn't ever need to alloc your own NSNotification object.
You generally pass "self" as the "object" of the notification as you say, but you could also pass something else in if you are notifying "on behalf of" something else, conceptually. But that would be less common case.
Notifications aren't the same as "events" in the UI. Cocoa does have events; they are mouse/keyboard/touch events, and they do "bubble" up the "responder chain" through the UI objects. Notifications are a totally independent mechanism that is not tied to UI, and it is used for generally global broadcast among otherwise decoupled/independent objects. It's more akin to having multiple delegates for an object.
Yes, you should define the name of the notification somewhere that everyone who uses it can see. In Cocoa itself, this is usually a public header with a declaration like extern NSString *const UIKeyboardDidShowNotification. In some private implementation file is the definition.
A special note regarding your #4 above. Think of notifications as notifications, not as instructions. They usually capture state changes or broadly interesting events. "MenuItemTapped" is a reasonable thing to notify about, but "NavigateTo" usually isn't, because the implication is that you're telling some specific object to navigate somewhere. If that's the case, that object should probably be a delegate (or should be a property) of the thing that wants the navigation, and you should cause it to happen directly. This isn't a requirement, of course, and you can use the mechanism for whatever you want. But the Cocoa design patterns generally don't use notifications for "telling objects what to do", only for "telling whoever cares what will/did happen". Make sense?
Finally, specifically re: your examples in #4-- those sound like genuine UI events, and seem like the whole thing could be handled via delegation, unless there's some reason why those objects need to be so decoupled.
You can directly create NSNotification objects if you so wish. postNotificationName:object: is just a convenience method that creates, configures and posts a notification object for you.
You can pass any object you like. Its purpose is to allow notification subscribers to only receive notifications about a particular object, so ideally you pass in the object the notification is about, which will often - but not always - be self.
Notifcations are not events. They're global broadcasts within the application.
You don't send notifications to a particular object - They're broadcasts. If you want to send a message to a particular object, you just call a method on that object.
Externs in the header file are fine.
I am new to mac os X development ,I downloaded an open source mac application ,but i couldn't able to understand the flow of execution of cocoa program.so any one can explain the program flow of a general cocoa program briefly.
Thanks in advance
Start in main. It's not likely to contain anything interesting, but worth checking just in case. Most probably, it will contain only a call to NSApplicationMain, which will create the NSApplication object and send it a run message. That's what gets the application running, and this method will run for the rest of the rest of the process.
Then look in the MainMenu nib. Loading this is one of the first things the application will do. Any windows here that are set as “Visible on Launch” will come up immediately; more importantly, the application delegate will probably be here. Check the application's or File's Owner's (the application is both of them in this nib, so you need to check both) delegate outlet, and if one of them is connected, follow the connection. See what class that object is an instance of.
Once you've found the application delegate class, open it up in Xcode. Look through the list of application delegate methods and find which ones are implemented, and read the ones that are. The application:…FinishLaunching: twins will be particularly important at the start of the process.
From there, it's all just reading code, seeing what it does, and going where it takes you.
Peter's answers are good - I'd also say to check for implementations of 'awakeFromNib', especially for object loaded from MainMenu.nib. You often find interesting things stashed away in that method, rightly or wrongly.