Take the 2-minute tour ×

This is currently what I have for my init,

- (id)init 
    self = [super init];

    if (self) {
        self.url = [[NSURL alloc] init];
        self.blurb = [[NSString alloc] init];
        self.author = [[NSString alloc] init];

    return self;

It does nothing, but I have another method called initWithObject: that will use its argument to fill up the instance variables url, blurb, and author. I don't know what I should be doing with this init. Should I throw an exception? What other options do I have?

share|improve this question
Are you using ARC? –  hypercrypt Oct 31 '11 at 22:01
I am using ARC. Does it make a difference for my question? –  awfullyjohn Oct 31 '11 at 22:39
Only that self.url = [[NSURL alloc] init]; would be a memory leak if you weren't (as I am sure you know). I assumed you were, just double checking. –  hypercrypt Oct 31 '11 at 22:46

5 Answers 5

up vote 10 down vote accepted

If you want to override your standard -init method you could either return nil (if you do not want -init to be used) or do:

- (instancetype)init
    return [self initWithObject:nil];

If you want to stop the use of -init completely you can tag it as an unavailable attribute or use NSAssert:

// .h
// ...

- (instancetype)init UNAVAILABLE_ATTRIBUTE;

// ...

// .m
- (instancetype)init
    NSAssert(NO, @"This method should not be used");
    return nil;

You can use either UNAVAILABLE_ATTRIBUTE or NSAssert(), but if you use UNAVAILABLE_ATTRIBUTE you need some kind of implementation of -init, even if it just returns nil.

share|improve this answer
I'm not sure what is safer here, returning nil will mean I do not crash but it will probably introduce some subtle logic error later on. I think for me I would rather my program crash so I resolve the error, which is most likely programmer error not using the correct designated initializer or one of its variants. –  Paul.s Oct 31 '11 at 22:22
See my updated answer –  hypercrypt Oct 31 '11 at 22:31

You don't have to have a plain init—you can simply have your initWithObject: method. If you're doing any basic setup that will remain the same 80% of the time, or if you have some common code in all your initializers, you can override init, but you are not required to.

Also consider changing your initWithObject: name to be more specific, to something like initWithPost: (I'm assuming this is some kind of blog-entry fetcher based on your ivars) so it's more apparent what object is desired.

share|improve this answer

I think you misinterpreted what you read. I don't think you would throw an exception. You could; however, leak memory. If your initWithObject: method looks like this:

- (id)initWithObject:(id)obj {
     if ((self = [self init])) {
              self.url=[obj url];
              self.blurb=[obj blurb];
              self.author=[obj author];
     return self;

And you would be perfectly fine. You could get an exception if your object was instantiated with -init and you used a variable which was assigned, assuming it was real. So in your subsequent methods be sure to check that the objects exist before using them.

If you made your object with -init rather than -initWithObject this could throw an exception:

- (void)dealloc {
         [url release];
         [blurb release];
         [author release];
         [super dealloc];
share|improve this answer

The rule that Apple has established for Cocoa programming is that every class must have one initializer method which is the "Designated Initializer". Every other initializer for the class must call that D.I.* The D.I. itself must call the superclass's D.I. Generally, the initializer with the greatest number of arguments (the one that most completely specifies the state of the new object) is the D.I.

In your case, with the bare init, and initWithObject:, the second would likely be the D.I. You would therefore override init to call initWithObject: with some default argument:

- (id) init {

    return [self initWithObject:[Object objectWithURL:[NSURL URLWithString:@"http://www.apple.com"]

This will result in a sort of dummy object, which is correctly initialized with useless data. (Outside of ARC, be sure to watch the memory management of the default argument(s) -- you want to use an autoreleased/unowned object(s).)

*Sometimes an exception is made for initWithCoder:.

share|improve this answer

If you have any method that you don't want called and that you don't want your subclass to support, throwing an exception in a Debug build is perfectly reasonable.

share|improve this answer

Your Answer


