0

I creating set of objects same custom type. All objects have methods showDeleteButton had hideDeleteButton. I found that when I hide delete button (remove it) button which was pressed has retainCounter == 2.

Here the code:

-(void)showDeleteButton {
if(!isDeleteButtonLoaded) { // Check that method was't triggered twice
    UIButton *aDeleteButton = [[UIButton alloc] initWithFrame:CGRectMake(-3, -7, 30, 29)]; // RC == 1
    [aDeleteButton setImage:[UIImage imageNamed:@"close_button.png"] forState:UIControlStateNormal];
    [self addSubview:aDeleteButton]; // RC == 2
    [aDeleteButton addTarget:self action:@selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    deleteButton = aDeleteButton;
    [aDeleteButton release]; // RC == 1
    isDeleteButtonLoaded = YES;
    NSLog(@"delete button retain count (created): %d", [deleteButton retainCount]);
    [self setNeedsDisplay];
}

}

-(void)deleteButtonPressed:(id)sender {
[delegate deleteImageAtPath:self.imageFullPath];

}

-(void)hideDeleteButton {
if(isDeleteButtonLoaded) {
    NSLog(@"delete button retain count (before): %d", [deleteButton retainCount]); // RC == 1
    [deleteButton removeFromSuperview]; // RC == 0
    deleteButton = nil;
    isDeleteButtonLoaded = NO;
    [self setNeedsDisplay];
}

}

So for pressed button NSLog in the second method displays RC == 2! Any ideas? I'm 100% sure that deleteButton isn't accessible from outside the class.

OgreSwamp
  • 4,392
  • 3
  • 31
  • 52
  • I'll add some explanation. Views contained those methods added to the UIScrollView. After I show delete button, press it and hide it I notice that in UISrollView one more subview appears - UIImageView. I'm sure that I don't add it manually. I checked that few times. There is no addSubview: called. So I just this that it might be some cached data from deleteButton... – OgreSwamp Jun 14 '11 at 17:24
  • So hierarchy is: UIScrollView has 3 MyCustomView (with methods mentioned above). MyCustomVew has 'optional' subview `deleteButton`. After loading `deleteButton` in UIScrollView one more subview appears with UIImageView class.. I'm trying to find what is the reason. – OgreSwamp Jun 14 '11 at 17:51

4 Answers4

5

DO NOT LOOK AT RETAINCOUNT

ahem

retainCount is meaningless as far as any sane person is concerned, as long as you're following the memory rules things will work out fine.

Joshua Weinberg
  • 28,320
  • 2
  • 95
  • 90
0

Never look at the retainCounts for any useful information. Within Apple's inner framework, they may call retain or release on your objects at any time. All you need to worry about is that your retain (or alloc, or copy) and release statements are matched up correctly. Adding a view as a subview of another view (or adding it to any NSArray) will also increase its retainCount... you don't need to worry about that though.

GendoIkari
  • 11,134
  • 6
  • 58
  • 100
0

See that stackoverflow popular question, about why never using retainCount and instead using Apple tools to track memory leaks.

Community
  • 1
  • 1
Vincent Guerci
  • 14,094
  • 4
  • 47
  • 55
0

Don't ever use retainCount. The results are misleading at best.

First order of business, go read Apple's memory management guidelines.

Second, use those guidelines to fix some memory issues in your code:

UIButton *aDeleteButton = [[UIButton alloc] initWithFrame:CGRectMake(-3, -7, 30, 29)];
// Retain count +1
// Some code...
deleteButton = aDeleteButton;
[aDeleteButton release];
// Retain count -1

You allocate a new UIButton and then you release it. This means the button is NOT owned by you and could disappear at any time. I'm guessing that you have a property in your class called deleteButton? If so, use it like this: self.deleteButton = aDeleteButton;

In your hideDeleteButton method, you probably want to use something that looks like this:

[self.deleteButton removeFromSuperview];
self.deleteButton = nil;
isDeleteButtonLoaded = NO;
[self setNeedsDisplay];

Again, this assumes that you have a property in your class named deleteButton. If you don't have one, make one and use it. It greatly simplifies memory management tasks.

kubi
  • 44,308
  • 19
  • 90
  • 118
  • There is no issues in my code AFAIK. [self addSubview:aDeleteButton] increase retain counter and that's mentioned in the documentation. – OgreSwamp Jun 14 '11 at 17:33
  • Why it assumes that I have a property BTW? there is no self.xxx syntax in my code. I just use class member `deleteButton`. I think I don't need to create properties for such easy situations... – OgreSwamp Jun 14 '11 at 17:36
  • There's no issues because you are either A) lucky or B) very good at tracking the retain/release of your objects in your head as you write code. Your `deleteButton` ivar depends on the state of `self.view` to remain valid. That's a fragile position to put yourself in and there's no reason to do it. If you want to hold a reference to `deleteButton` you should retain yourself. – kubi Jun 14 '11 at 17:39
  • You don't need to create a property, but if you aren't, you should practice proper memory management. `Retain` objects if you want to hold a reference to them, `release` objects when you're finished. – kubi Jun 14 '11 at 17:43
  • Yes deleteButton depends on the state of its superview (self in this case). If I'll release superview it will release deleteButton. That is quite logical IMHO... Thanks anyway :) – OgreSwamp Jun 14 '11 at 17:47