0
votes

@interface:

UIImageView *myImageView;

@property (nonatomic, retain) UIImageView *myImageView;

@implementation:

@synthesize myImageView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.myImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
}

What is the reference count for myImageView? 2 (1 from alloc, 1 from dot notation retain) or 3 (1 from alloc, 1 from dot notation retain, 1 from @property retain)

Do these two statements have the same reference count?

self.myImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];

and

myImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];

Also, I assume you release them in @implemenation and in dealloc method, correct?


EDIT:

I didn't get the answer that I wanted, maybe my question is vague. I understand what dot notation, @property, @synthesize, and how setter and getter works. What I don't understand is what happen when using "self." and without "self." regarding retain count. I actually ran retainCount method on myImageView object and it confirms my original, the "self." case has a retain count of two off the bat (with alloc and property retain so it's probably a good idea to use autorelease there). Now this lead to another question, if I were not to use autorelease, how do I go about this? release once in viewDidLoad and once more in dealloc would still result in a memory leak, right?

self.myImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
NSLog(@"retain count dot: %d", [myImageView retainCount]);

2011-05-17 10:01:14.915 Test[1249:207] retain count dot: 2

myImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
NSLog(@"retain count: %d", [myImageView retainCount]);

2011-05-17 10:03:14.715 Test[1278:207] retain count: 1

3
Don't think of retain counts as absolute values; think of them as deltas. I.e. "alloc yields an object w/reference count +1", "self.myImageView = aView adds one to the reference count", "release decrements the retain count by one"..... - bbum
@bbum, understood but what I am trying to grasp is the differences when using the property assessor and ivar directly. Do I still have to release both in viewDidLoad (since I alloc there), and release it again in dealloc because it is a retain property. - s2000coder
Count the retains you are causing and balance every one with a release; +alloc is one, the assignment to the property through the setter is another... so, yes, you need two releases or autoreleases. It is that simple; if you retain, you must release. - bbum
so for the second case using the @property assessor, I have to release it twice, one in viewDidLoad for the +alloc and release in dealloc for the retain? What about the first case? - s2000coder

3 Answers

2
votes

First: you shouldn't make any assumptions about the reference count. It will be misleading at best.

If you use the property access (self.myImageView = ...) then it will get retained automatically, thus you are leaking the UIImageView in viewDidLoad. You should use something like

self.myImageView = [[[UIMageView alloc] init.... ] autorelease];

Your last example (without the "dot" access) will modify the ivar directly, so it will not leak this new instance. BUT it will leak the old imageView that you override if you don't release it before.

I strongly recommend using the property access all the time. And don't forget to clean up in dealloc:

[myImageView release], myImageView = nil;

Some people prefer self.myImageView = nil; but this may have side effects.

1
votes

no, they are not the same. The first one does "retain", thus increasing the reference count. So either you assign it first to a temp variable and then release (in the first case) [alternatively, add 'autorelease' and get away w/o temporary variable], or you check that there's no imageView assigned already (and if there's - release it) in the second case.

0
votes

To add to the first answer, the dot notation setter takes care of the memory management involved with releasing the old object and retaining the new one. In the second case you would have a huge potential memory leak on your hands, since every time this is called, the retain goes up by 1. Not the case with the dot notation setter.

Since it is retaining the object, however, you do need to release the original allocation.