7

I have a very strange issue with the xCode 4.3 memory leak instruments... Basically it does not work in the following case...

  1. Project is created without ARC support.
  2. Create a simple class which inherits UIView
  3. use a "button" to create instance of this class and "leak" it... the leak will not be catch by Leak Instruments

so here is the code of the PROBLEMATIC class

@interface LeakTestView :  UIView
- (id)initWithFrame:(CGRect)frame;
@end

@implementation LeakTestView
- (id)initWithFrame:(CGRect)frame
{
    NSLog(@"initWithFrame called");
    self = [super initWithFrame:frame];
    if (self) {

        // Initialization code
    }
    return self;
}
@end

And now I create the leak...

- (IBAction)leak:(id)sender {
    LeakTestView* leak=[[LeakTestView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    NSLog(@"class is %@", [leak class]);
}

So the problem is that this leak will not be detected...

If I change the base class to NSObject and instead of initWithFrame override init (see bellow) then the leak will be detected....

so here is the code for leak that WILL be detected

@interface LeakTestView : NSObject
- (id) init;
@end


@implementation LeakTestView

- (id) init {
    NSLog(@"init called");
    self = [super init];
    if (self) {

    }
    return self;
}
@end

If I create object now and leave it - the leak detection will trigger and the leak will be "seen" into the Instruments.

- (IBAction)leak:(id)sender {
    LeakTestView* leak=[[LeakTestView alloc]init];
    NSLog(@"class is %@", [leak class]);
}

Any ideas what is going on? Why the leak of the UIView subclass will not be detected but changing the base class to NSObject will "fix" the issue? Oh and yes the leaked object can be seen using the "Mark heap" - one mark before the leak and one mark after I click the button and create the leak - the class will be seen into the heap delta...

EDIT: one more "funny" situation... If I remove the "init" stuff (only alloc the object)

LeakTestView* leak=[LeakTestView alloc];

then the leak will be detected no matter what is the base class... What the hell is going on here?

EDIT2: one more "funny" thing. The Leak detection issue can be observed only in Simulator (iOS 5.0, 9A334 is mine) but the leak will be detected always if using the iPad device...

Any comments? If you dont have the issue or consider that I speek "lies" just tell me I am wrong and the above case is working "just fine" - leaks I describe are detected by your xCode instruments!

Simon Hayter
  • 3,131
  • 27
  • 53
Sunman
  • 73
  • 2

1 Answers1

0

Maybe it is not leaking?

You are calling a method that is a black box. How UIView initWithFrame is implemented is none of your business. It has a contract of sorts, but you have no right to demand this to leak anymore than you can assume the retain count is 1.

Leaks is a useful tool but it doesn't do what you think it does. It does not tell you when you have messed up. It tells you when you have unreachable allocations. This is not the same thing.

Or, it might be a bug.

Simon Hayter
  • 3,131
  • 27
  • 53
hooleyhoop
  • 9,128
  • 5
  • 37
  • 58
  • Thanks for the answer. I know that Leaks detects unreachable allocations (and this tool is not a "magic" solution to show where the problems into the code are), but if I check the retain count of the "leaked" object it says 1 (as it should) so the only retain that is "active" is from the alloc. So for me there is a leak that the Instruments can not "find" even it is "so simple one". It is really easy to create a sample project to test it by your self - just use the Simulator and leak a subclass of UIView, and check will the Instruments find it... – Sunman Feb 28 '12 at 13:50
  • I know, i totally agree it is weird, but the retain count really, really is telling you nothing. Ignore it > http://www.friday.com/bbum/2011/12/18/retaincount-is-useless/ – hooleyhoop Feb 28 '12 at 15:10
  • I know that retain count can not be used to say "how many external objects reference me" because of the @property implementation and may other factors but in some cases it gives information what is going on - and in the above case it guaranties that the only reference to the newly created object is from the alloc and the initWithFrame does not increment the retain count and in this way preventing the Leaks Instrument to find the leak... – Sunman Feb 28 '12 at 15:22