Leaks & Zombies

26
& Zombies Leaks Teemu Kurppa Co-Founder, Huikea.com A quick intro to iPhone memory management

description

A BarCamp presentation about iPhone memory management programming. Teemu Kurppa gave this at MobileDevCamp Helsinki (http://MobileDevCamp.fi)

Transcript of Leaks & Zombies

Page 1: Leaks & Zombies

&ZombiesLeaks

Teemu KurppaCo-Founder, Huikea.com

A quick intro to iPhonememory management

Page 2: Leaks & Zombies

BasicsNSString* s = [[NSString alloc] init]; ➊[s release]; ⓪

Page 3: Leaks & Zombies

NSString* s = [[NSString alloc] init]; ➊[s retain]; ➋[s release]; ➊[s release]; ⓪

Basics

Page 4: Leaks & Zombies

AutoreleaseNSString* s = [[[NSString alloc] init] autorelease]; ➊

Page 5: Leaks & Zombies

NSAutoreleasePool* pool = [[NSAutoreleasePool] alloc] init];

...

NSString* s = [[[NSString alloc] init] autorelease]; ➊ ...

[pool release]; ⓪

Autorelease

Page 6: Leaks & Zombies

NSString* s = [NSString string]; ➊[pool release]; ⓪

why? because:

@implementation NSString

+ (NSString*)string { return [[[NSString alloc] init] autorelease];

}

@end

Factory methods

Page 7: Leaks & Zombies

- (void)setFoo:(Bar*)aFoo { [_foo release]; _foo = [aFoo retain]; // Incorrect, why?}

An incorrect setter

Page 8: Leaks & Zombies

- (void)setFoo:(Bar*)aFoo { if (aFoo != _foo) { [_foo release]; _foo = [aFoo retain]; }}

A correct setter

Page 9: Leaks & Zombies

- (void)setFoo:(Bar*)aFoo { [_foo autorelease]; _foo = [aFoo retain];}

A correct setter

Page 10: Leaks & Zombies

4 Rules of Thumb1 Use autorelease for temporaries2 Retain & release members3 Use properties to get correct setters4 Break rule 2 to avoid retain loops

Page 11: Leaks & Zombies

- (void) foo { NSString* s = [NSString string]; ➊ or NSString* s = [[[NSString alloc] init] autorelease]; ➊}

Rule 1: Use autorelease for temporaries

Page 12: Leaks & Zombies

@interface Bar { NSString* _name;}@end

- (id) init { if (self = [super init]) { _name = [[NSString alloc] init]; } ➊ return self;}

- (void) dealloc { [_name release]; ⓪ [super dealloc];}

Rule 2: Retain & release members

Page 13: Leaks & Zombies

@interface Bar { NSString* _name;}@property(retain) NSString* name;@end

@implementation@synthesize name = _name;

- (void) dealloc { [_name release]; // still important! [super dealloc];}

Rule 3: Use properties to get correct setters

Page 14: Leaks & Zombies

@interface Bar { id _delegate;}@property(assign) id delegate; // Note: not retain!@end

@interface Foo { Bar* _bar;}@end

in Foo:

_bar = [[Bar alloc] init];_bar.delegate = self;

Rule 4: Break rule 2 to avoid retain loops

Page 15: Leaks & Zombies

What about bugs?

Page 16: Leaks & Zombies
Page 17: Leaks & Zombies

- (void)init { if (self = [super init]) { _foo = [[NSString alloc] init];

➊}

- (void)dealloc { [super dealloc];}

A leak

Page 18: Leaks & Zombies
Page 19: Leaks & Zombies

- (void)init { if (self = [super init]) { _foo = [NSString string];

}

- (void)foo {NSLog(@”Foo is %@”, _foo);

}

Premature delete

Page 20: Leaks & Zombies
Page 21: Leaks & Zombies

- (void) f { Bar* bar = [NSString string];

➊ _foo = bar;}

... [pool release]; // ⓪

- (void)dealloc { [_foo release]; !!! -1 [super dealloc];}

Double-deletion

Page 22: Leaks & Zombies
Page 23: Leaks & Zombies

NSZombieEnabled

Zombies to help

Page 24: Leaks & Zombies

NSZombieEnabled

Zombies to help

Page 25: Leaks & Zombies
Page 26: Leaks & Zombies

by lunchtimemama http://www.flickr.com/photos/lunchtimemama/97685452/sizes/o/

by Rachel Cobcroft http://www.flickr.com/photos/felix42/453311029/sizes/o/