How should I handle a failure in an init: method in Objective-C?
Asked Answered
L

3

24

Let's say I'm building a new class for the iPhone in Objective-C. In one of my init methods I want to manually allocate some memory. So, I might have something like this:

- (id)initWithSomeObject:(SomeObject *)someObject {
  self = [super init];
  if (self != nil) {
    myObject = someObject;
    [myObject retain];
    if ( (memory = calloc(1, sizeof(SomeStruct)) == NULL) {
      // What should I do here to clean up
      [self release];
      self = nil;
    }
  }
  return self;
}

Now, assuming that the calloc() could fail, and that failing to allocate memory is catastrophic for my object, what should I do inside the if-body to clean up properly? Is there an Objective-C idiom or pattern that I should be using?

Edit: I included the code posted by Rob Napier. But, I still have to release myObject, right? Or does the added code somehow trigger dealloc()?

Lazulite answered 6/1, 2010 at 22:27 Comment(2)
Don't worry about whether it triggers dealloc(). It does, but that's not the point. The point is that [self release] balances the earlier call to +alloc, so all your required releases have been done and the system will now take care of deallocating at the appropriate time. In most cases, "the appropriate time" is likely as soon as [self release] is called, but it could be later if there are any pending autoreleases. But the code above is correct and nothing else is required.Diallage
As a side note: It is my understanding that calloc/malloc will never return NULL, the system will just kill your App when you run out of or low on memory. I guess Apple figured that was easier to do that then have App crashing from unchecked NULL/nil pointers.Sundin
D
27

Yes, you should release yourself and then return nil.

[self release];
self = nil;

See Issues with Initializers in the Concepts in Objective-C Programming guide.

Diallage answered 6/1, 2010 at 22:31 Comment(0)
G
3

You need to clean up anything you need to and then set the self reference to nil. Apple Dev Portal has an article:

Link

Genevieve answered 6/1, 2010 at 22:33 Comment(1)
Don't forget to release self, or you'll leak. (No idea who downvoted; you're right).Diallage
B
1

I just tried. -dealloc gets called due to [self release], so myObject would not need to get released in initWithSomeObject. To be sure, you might move myObject = [someObject retain]; (I prefer that style in case -retain might fail for some reason) below the call that might fail (if that's possible).

Bernardinabernardine answered 6/1, 2010 at 23:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.