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()?

Rob Jones
  • 4,925
  • 3
  • 32
  • 39
  • 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. – Rob Napier Jan 07 '10 at 18:17
  • 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. – Roger Gilbrat Nov 29 '11 at 21:23

3 Answers3

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.

jscs
  • 63,694
  • 13
  • 151
  • 195
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
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

psychotik
  • 38,153
  • 34
  • 100
  • 135
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).

MrMage
  • 7,282
  • 2
  • 41
  • 71