1

How should I set a retained property when creating an object using alloc and init? (Without using autorelease)

With this line in the header (and the corresponding @synthesize line in the implementation):

@property(retain)UIWebView *webView;

These are the three options I have (I think):


UIWebView *tempWebView = [[UIWebView alloc] init];
[tempWebView setDelegate:self];
tempWebView.hidden = YES;
self.webView = tempWebView;
[tempWebView release];

(This one seems the best concerning memory management but it's more lines of code and involves a stupid variable name, so a decrease in readability)


self.webView = [[UIWebView alloc] init];
[self.webView release];
[self.webView setDelegate:self];
self.webView.hidden = YES;

(This one it's more obvious whats happening but the memory management doesn't seem that great, also Xcode's Analyser doesn't like it)


webView = [[UIWebView alloc] init];
[self.webView setDelegate:self];
self.webView.hidden = YES;

(This one is the shortest, it's more obvious than the first example whats happening. But it bypasses the setter, so should a custom implementation of the setter be implemented later it won't work in this case)


So which example should be used, or is there a better way?

Jonathan.
  • 53,997
  • 54
  • 186
  • 290

1 Answers1

1

The best option, IMO, is the one you don't like, i.e. using autorelease:

 self.webView = [[[UIWebView alloc] init] autorelease];

If you do not want to and want a one-liner initialization, the only option is your third one:

 webView = [[UIWebView alloc] init];

since all the others requires an explicit line to do an extra release.

I don't see it as bad, especially when it belongs to the init method and you don't reassign it elsewhere without using the property, and I myself use it when it seems reasonable to me.

What works really well with retained properties are convenience constructors like:

self.image = [UIImage imageWithContentsOfFile:xxxxxxx];

So, possibly if you really find that none of the options you listed is fine with you, you might add a category to UIWebView and a convenience constructor doing the autorelease job for you:

self.webView = [UIWebView webViewWith......];
sergio
  • 68,819
  • 11
  • 102
  • 123
  • 1
    Keep in mind that the third option does not release the previous value of `webView`. It would be my preferred option in initializers, since usage of accessors is discouraged in initializers, but not in other methods where you would have to make sure to release the previous value. – albertamg Jul 15 '11 at 10:58
  • Agreed, that is why I wrote: "especially when it belongs to the init method"... your comment makes perfectly clear what I meant by it, although I expressed it no so well... :-) so you are left with the convenience constructor option... :-) – sergio Jul 15 '11 at 11:03
  • I had not seen your edit by the time I wrote the comment. I just wanted to make that clear :) – albertamg Jul 15 '11 at 11:08
  • The only reason I said without autorelease is because I had gathered that you should avoid it unless you need it. So should I `alloc`/`init` all properties in the parent's `init` method? Or should I `alloc`/`init` them as I need (eg in `viewDidLoad`)? – Jonathan. Jul 15 '11 at 11:17
  • @Jonathan. To autorelease, or not to autorelease, that is the question. Some programmers prefer to avoid it whenever possible; others argue that the overhead of using autorelease is meaningless in most scenarios. To follow up, see [this question](http://stackoverflow.com/questions/5874697/why-is-release-often-called-shortly-after-a-local-var-is-used-instead-of-just-aut/5874764#5874764), [this one](http://stackoverflow.com/questions/5860639/autorelease-for-beginners/5860872#5860872) and [another one](http://stackoverflow.com/questions/193288/what-is-the-cost-of-using-autorelease-in-cocoa). – albertamg Jul 15 '11 at 13:34