Where is My Object Retained?

Wed, Aug 13

For those new to Objective-C and iPhone development, I want to point out something that might save you some time. Look at the code below:

1
2
3
4
5
6
@interface SomeClass : UIViewController
{
  ..
  UIView *containerView;
  ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
@implementation SomeClass
...
- (void)loadView
{
  ...
  UIView *uiView = [[UIView alloc] initWithFrame:
     [[UIScreen mainScreen] applicationFrame]];
  self.containerView = uiView;
  [uiView release];
  ...
}
...
@end


In this block of code, I am setting up a container view, that will hold several subviews. Once the assignment is complete on line 8, I release the local object uiView. Question is, how I can I get away with releasing the variable and still have access to the view in the SomeClass object? In other words, where is the retain?

First thing to notice is that the dot syntax is shorthand for accessing class instance variables using Objective-C properties. If one were to write the code without using properties (and thus, no dot syntax) the answer is obvious.

For example, the equivalent code directly calling the accessor (setter) method would look as follows:

1
2
[self setContainerView:uiView];
[uiView release];

At this point, if one was curious about where the object was retained (before the release), the obvious place to look is inside the setter, which might look as follows:

1
2
3
4
5
6
- (void) setContainerView:(UIView *) view
{
  [view retain];
  [containerView release];
  containerView = view;
}

Easy enough, the object is retained as part of the setter. What we have here is a good example of pro’s/con’s when working with properties. On one hand, properties allow for simplification and consistency in our code. On the other hand, if using properties and we request the compiler to implement the getter/setter methods (through use of the @synthesize directive) there is code created for us to implement these methods, which we never see.

Although properties are no doubt handy, as this example illustrates, it’s important to understand what is happening behind the scenes. A clear picture of the little nuances can go a long ways when it comes to debugging a thorny problem.

2 comments

Just to add…

If you do use properties with the @property directive you can specify the declaration attributes. In this case you could use:

@property (retain) UIView *containerView

This will tell the compiler to use retain the value passed in when synthesizing the accessors. The default is assign, which implements accessors which assign (using =) the values passed. This makes it easier to know when you can release objects passed into accessors.

by stompy on Aug 14, 2008. Reply #

Is there any documentation anywhere of the exact code that @property and @synthesize automatically generate for setters? I’ve read Wil Shipley’s “pimp my code” series and he talks about the virtues of checking for equality between the old value and new value for an object before doing the retain/release dance, and at least in some circumstances I may want to do that on some setters.

by Richard Cook on Aug 19, 2008. Reply #

Leave a Comment