Alloc init


#1

I noticed on someone else’s solution they used alloc init. I did not. But mine still seems to work. Here is my code:

[code]
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{

@autoreleasepool {
    
    NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
    NSLog(@"My time zone is %@", timeZone);
    
    NSInteger yesNo = [timeZone isDaylightSavingTime];
    if (yesNo) {
        NSLog(@"It is daylight savings time.");
    }
    else
        NSLog(@"It is not daylight savings time.");
    
    
}
return 0;

}[/code]

Should I have used alloc init and why or why not?


#2

Before ARC, there was a difference between [[NSTimeZone alloc] init] and [NSTimeZone systemTimeZone] in terms of memory management. With ARC, there is really no difference. (There is a “For the More Curious” section on retain counts later in the book. You can figure out the difference there.)


#3

But in the beginning of chapter 13, it is said that using alloc and init is not just good practice, it is “the only Apple-approved way”…
If I look in the documentation of for instance NSDate, there’s a list of possible creation methods, including class methods like ‘+date’.
Why would I use NSDate *now = [[NSDate alloc] init]; instead of NSDate *now = [NSDate date];

Eventually the +date calls the alloc init anyway…


#4

I’m also curious about whakkee’s question (above)

In addition to that, if you wanted to use the 2nd example he posted would be:

NSDate *now = [NSDate date alloc ] init ];

or maybe

NSDate *now = [NSDate date ] [alloc] [init]];

When nesting alloc / init the [ ]'s get a little confusing

?

I’m not sure the proper syntax when “date” is in there if I wanted to use alloc and init as well.


#5

I covered this on a chapter 12 thread: viewtopic.php?f=144&t=3299#p6775

Specifically to your question, Bryan, [NSDate date] creates an object and initializes it, so alloc/init do not apply at all.

Edit: Heh, sorry Bryan, forgot it was you I was exchanging ideas with on that thread.

Anyway, to answer whakkee’s question directly: if there’s a message you can pass to a class or object that creates and initializes the object you need in the way you need it, you should absolutely use that instead of alloc/init.


#6

I’m a new user on the forum (this is my first post), and it seems like this might have been beat to death (and, yes I’ve been reading all the posts on this topic), but…

It seems that for the “Apple approved way” of using alloc and init, you might end up with some problems.

To whit, example 1 (for NSDate):

NSDate *now = [[NSDate alloc] init]; // NSDate is immutable, so need to assign value after init?
NSLog(@"The date now is %@", now);

Example 1, despite the init message, still has a proper value, as NSLog will show (because NSDate is immutable?), but…

Example 2 (for NSTimeZone):

NSTimeZone *sysTimeZone = [[NSTimeZone alloc] init]; // Properly init the object!
NSLog(@"The system time zone is %@", sysTimeZone);

Will cause a NULL value to be stored in sysTimeZone, i.e. NSLog gives: The system time zone is (null).

You have to assign the value to it like this:

NSTimeZone *sysTimeZone = [[NSTimeZone alloc] init]; // Properly init the object!
sysTimeZone = [NSTimeZone systemTimeZone]; // Put a value into the object, otherwise is null
NSLog(@"The system time zone is %@", sysTimeZone);

NSLog now gives: The system time zone is America/Denver (MST) offset -25200.

So for those who thought they might be getting the right value (i.e. not DST), when using the alloc/init protocol on page 81, that NULL may have been giving a false positive in their test for isDaylightSavingTime. Or, is the object returning the correct value for isDaylightSavingTime regardless of the init? I read through the NSTimeZone reference, and got the same results with other messages, for example defaultTimeZone.

Did I just completely miss something, or should Aaron have pointed out that after an [[NSsomeclass alloc] init], we should assign a value to the now initialized object?


#7

I glossed over whakkee’s question about the “Apple approved way.” Now that I’ve looked at chapter 13, Aaron is saying that when you call alloc/init in sequence, the only approved way to do so is on one line. He is not saying that the only approved way to create an object is via alloc/init.

8bitVet: if you look at Apple’s documentation for NSTimeZone, init is not documented (and therefore should not be used). Instead, two variations on initWithName: are provided, and in the overview there are several class methods listed as alternatives to alloc/initWithName.

In summary: before you use a class with which you’re unfamiliar, take a look Apple’s docs, and pay particular attention to any mention of creating objects in the Overview section, and to the Creating and Initializing methods listed.


#8

macintux:

Thanks, I haven’t quite come up to speed on the (apparently) esoteric ability to read what I need to know out of the Apple documentation. The direction is appreciated.

So, technically nobody should be using init in their challenge examples for NSTimeZone?

Lastly, am I correct in assuming that without assignment, and using an alloc/init, the null value returned by isDaylightSavingTime could create an error, i.e. a null value read as FALSE, that the isDaylightSavingTime has not operated on a proper message?

Thanks again.


#9

It’s not the easiest stuff in the world to read, but it gets better over time. Wounds heal. :smiley:

It’s always safest to avoid undocumented behavior. Even if you can find a way to make alloc/init work for NSTimeZone, there’s no guarantee that the next library change, or Xcode upgrade, or Mac/iOS release won’t break it.

Thanks for the question: this forced me to confirm something I speculated about in my blog, but couldn’t confirm at the time.

I knew that nil could be sent messages; the runtime system would provide a reasonable default false-ish value in return.

I was only reasonably confident that NULL would behave the same way (since apparently nil and NULL are both 0 values), and it does.

So yes: if you attempt to call isDaylightSavingTime on a NULL value, such as that returned by init for this class, you’ll get a false value, which is currently correct for all(?) of the northern hemisphere, and thus misleading.