Question about Challange code


I have two questions about this code… The challange asks to create two instances of NSDate. Am I correct that NSDateComponents *comps is the 1st instance, and NSDate *dateOfBirth is the 2nd instance?

My other question is why do NSDateComponents and NSCalander need alloc and init, but NSDate does not?

[code]NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:1969];
[comps setMonth:4];
[comps setDay:30];
[comps setHour:13];
[comps setMinute:10];
[comps setSecond:0];

NSCalendar *g = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *dateOfBirth = [g dateFromComponents:comps];[/code]


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.


I thought NSCalnder is allocating initializing the objected pointed to by g?

If a new instance of NSDate is being created called dateOfBirth, then why isn’t there an alloc / init pared with it?

If alloc and init are automatic with NSDate (or something else) then how can we tell when we need to write it in or code or not?

Thanks again!


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.


Thank you so much for breaking it down like that, it does makes a lot more sense now.


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.


I don’t know if it is late - or this code is making me blind - but how does program know that we want seconds returned and not years,months,days?


Which program?

Each method should be explicit about what it returns.

For example, if you look at … 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.


Is this why the following is used at the beginning of the chapter?




Thank you.

I just realized that I could have just read the next section in the book.