You actually do need 2 NSDate objects, which you’ll use to invoke the timeIntervalSinceDate: message. Both comps and dateOfBirth are related to your birthday; you’ll need another NSDate object to capture “now” to perform the calculation.
In the sample code, laterDate is an NSDate instance.
As far as the alloc/init combination, there are (at least?) two distinct ways to create an object. You can allocate the system memory and initialize the properties via alloc/init, or you can ask a class or object to do that for you.
So in the example code, dateOfBirth is created on your behalf by the NSCalendar object.
Good questions, especially your last. Let’s tackle that first.
If you read the Apple documentation on NSDate, you’ll see it’s a bit of an odd duck. Quoting:
In short, date/time handling in general is so ugly that Apple’s trying to keep any of us from making it worse than it already is, so NSDate objects have special initialization handling mechanisms, including the one Aaron shows us here.
More generally, let’s walk through the object creation code to make sure we’re aligned with what’s happening.
First, to make sure the baseline is set for the typical scenario: alloc is a class message that sets aside a block of memory for further use (same concept as malloc in C programming) and creates an object reference with no attributes, while init is sent to the resulting object to ask it to initialize its attributes as best it can in the absence of further information.
So alloc + init works for simple cases, and there are lots of simple cases when it comes time to create objects.
Above, comps is an NSDateComponents object created through our normal mechanism: class message alloc + object message init.
This is similar, but a little more specialized. g is an NSCalendar object with memory set aside via class message alloc, but the object initialization (its “setup” process, so to speak) is tailored for the Gregorian Calendar (vs. Buddhist, Chinese, Hebrew, Islamic, or a half dozen other options).
This is particularly tricky. Instead of calling alloc by way of the NSDate class, we’re asking the g object to create a new NSDate instance on our behalf, because g understands how the Gregorian calendar works, and can pinpoint the date components (supplied via the message dateFromComponents:) to an absolute point in time for later calculation. Somewhere behind the scenes, alloc is being called, but we don’t know where or against which class.
This is part of what made manual reference counting such a royal pain: you have to know more about where objects are allocated than what you should ordinarily care about.
When you start writing your own code using the Cocoa classes, you’ll need to pay attention to the recommended object creation mechanisms. Often alloc + init is fine, but occasionally there is a better way, either through a smarter init message (such as initWithCalendarIdentifier: above) or by asking a related class or object to create it for us with a smarter context.
You’re welcome. It’s helpful for me to walk through something like this carefully; I often find that explaining something really solidifies how it works for me (and typically forces me to do more research for a question that I’ve tabled for one reason or another previously, or to fix a broken assumption I discover during the explanation).
I found this very helpful, thanks! Yet I’m still baffled. How come that an NSCalendar object (in this case g) can create an NSDate object (in this case dateOfBirth)? Is that common? Would that be something I need look up in Apple’s Documentation on a class-by-class basis?
It isn’t uncommon for a method on one class to create and return an instance of another class.
For example, you might ask a text field what its contents are. It would create and return a string object as a response. Really, behind the scenes, it is using an NSString class method to create the string, but you can tell that when you call the text field’s method.
Each method should be explicit about what it returns.
For example, if you look at developer.apple.com/library/mac … rence.html, timeIntervalSinceNow is defined to return an NSTimeInterval, which as it turns out is a double value representing number of seconds. If you want to receive (or turn the NSTimeInterval into) a number of days, you’d have to find a different method.
@macintux - Thank You! I always get a little nervous when I look at Mac Dev documentation. To me it reads like a dictionary without a sample of the usage. I know there is sample code available but I wish they would provide a more brief example of usage. Concerning NSTimeInterval - thank you - I was suspecting the double and after reading the definition it all makes sense - thanks for pointing me to Apple Dev. I really need to get comfortable reading it.