Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to call initializers multiple times on the same 'alloc'ed object?

Tags:

objective-c

I can construct a UIImageView object with myImageView = [[UIImageView alloc] initWithImage:image];

Following application activity affecting the display, if I want to change the image on the UIImageView. I can do so by reassigning it with myImageView.image = someNewImage. However this doesn't seem to update the frame dimensions. I can modify those manually, but I have observed in practice that calling [myImageView initWithImage:someNewImage] does that for me, and has the advantage of being terser.

However I not sure if it is officially a breach of protocol in Objective C to make multiple calls to init methods on an object constructed by a single alloc. I wouldn't use it unless it was safe (guaranteed not to crash or cause leaks). Is there evidence that it is unsafe?

My research so far...

This article gives general detail about 'alloc' and 'init' on objects

http://developer.apple.com/library/mac/documentation/cocoa/Conceptual/ObjectiveC/Articles/ocAllocInit.html

This is related SO question

Why are alloc and init called separately in Objective-C?

This blog article warns suppliers of objects that their init methods may be called multiple times as an effect of the initialization process.

http://www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-times-load-not-so-much/

like image 400
Jim Blackler Avatar asked Nov 11 '10 10:11

Jim Blackler


2 Answers

No.

-init is written assuming that it is only called once. For example, -initWithImage quoted in Apple's documentation you quoted is implemented as

- (id)initWithImage:(NSImage *)anImage {
  ...
  if (self) {
      image = [anImage retain];
  }
  return self;
}

This assumes that the ivar image doesn't point to a retained object. If called twice, it leaks image.

Call -init... only once per alloc, and call -init... immediately after alloc by combining them as usual:

SomeClass* foo=[[SomeClass alloc] init...: ... ];

You should never separate them, because [anAllocedObject init...] might return something different from anAllocedObject.

like image 60
Yuji Avatar answered Sep 23 '22 06:09

Yuji


No, init (or one of it's variants) should only be called once on any object, as Yuji explained. As far as your UIImageView issue goes, I believe you can just call [imageView sizeToFit] after assigning your new image, and it will automatically resize it for you.

like image 28
BJ Homer Avatar answered Sep 21 '22 06:09

BJ Homer