Transcript
Page 1: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

Gestion Mémoire

Thomas DupontCocoaHeads Rennes #912 avril 2012

du débutant à l’expert

Page 2: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

Sommaire

• Gestion mémoire

• Compteur de références

• Properties

• Blocks

• ARC

Page 3: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

•Gestion mémoire

stack

sp

0

1

2

3

4

5

6

7

co if (b) {int y = 3;

}

Page 4: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

•Gestion mémoire

stack

sp

0

1

2

3

4

5

6

7

co if (b) {int y = 3;

}

adresse de retour : 4

variable y

Page 5: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

heap

•Gestion mémoire

malloc

free

Page 6: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

0

Compteur de références

retain

release

NSObject

12

Page 7: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

chien

Compteur de références

métaphore du chien

A B

C

0123

‣ Vous êtes responsable des objets que vous créez

‣ Vous pouvez devenir responsable d’un objet avec retain

‣ Vous devez relâcher un objet dont vous êtes responsable

Page 8: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

+ (id)alloc- (id)init+ (id)new- (id)copy- (id)mutableCopy

Conventions de nommage

Compteur de références

+ (MyObject*)fetchMyObject;

MyObject* obj = [MyObject fetchMyObject];

Page 9: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

obj

Compteur de références

autorelease

autoreleasepoolrun loop

obj01

Page 10: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

Properties

assignretain

readonlynonatomicsetter=

@synthesize myObj;

copy

getter=

NSObject* myObj;@property (attributes)

readwrite

Page 11: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

Blocks

dispatch_block_t myBlock

[UIView animateWithDuration:0.5 animations:

^{ myView.alpha = 0; }

];

= ;

myBlock

Page 12: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

int a = 3;__block

Blocks

void (^incrementA)(void) = ^{ a++; };

incrementA();

Page 13: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

Blocks

NSObject* myObj;__block

void (^foo)(void) = ^{ [myObj foo]; };

foo();

Page 14: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

Blocks

void (^foo)(void) = ^{myIvar++;[myObj foo];

};foo();

MyObject* myObj;int myIvar;

MyClass.h

MyClass.m

Page 15: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

myObj = [[MyObject alloc] initWithBlock:^{NSLog(@"%i",

}];

MyObject* myObj;int myIvar;

myIvar);

MyClass.h

MyClass.m

myObj

blockself

Blocks

Page 16: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

myObj = [[MyObject alloc] initWithBlock:^{NSLog(@"%i",

}];

MyObject* myObj;int myIvar;

MyClass* weakSelf = self;

weakSelf-> myIvar);

MyClass.h

MyClass.m__block

myObj

blockself

Blocks

Page 17: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

dispatch_block_t block;

if ( ... ) { if ( ... ) {

} else {

}

} else {

}

block();

int* pInt;

int a = 1;pInt = &a;

int b = 1;pInt = &b;

// utilisation de pInt

;^{ ... }block =

Blocks

;^{ ... }block =

Page 18: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

dispatch_block_t block;

if ( ... ) {

} else {

}

block();

copy] ;^{ ... }[[ autorelease]block =

Blocks

copy] ;^{ ... }[[ autorelease]block =

Page 19: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

@implementation Stack { NSMutableArray *array; }

@end

- (id) init {if (self = [super init])

array = return self;

}- (void) push: (id) x {

[array addObject: x];}- (id) pop {

id x = [array removeLastObject];return

}

;[[NSMutableArray array]

[array lastObject][ ;

;[

Page 20: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

@implementation Stack { NSMutableArray *array; }

- (void) dealloc { [array release]; [super dealloc]; }@end

- (id) init {if (self = [super init])

array = return self;

}- (void) push: (id) x {

[array addObject: x];}- (id) pop {

id x = [array removeLastObject];return

}

retain] ;[ [NSMutableArray array]

[array lastObject][ retain] ;

autorelease] ;[ x

Page 21: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

It just works !

Oublier la notion de retain et releasePenser au graphe d’objets

Insertion automatique de retain, release et autorelease

Page 22: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

__strong objc_retain (

objc_autorelease (

- (id) pop { [array removeLastObject] ;return

}

result =

ARC

__strong

[array lastObject] ;

; result

)

)

valeur par défaut

devient responsable

id

Page 23: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

__unsafe_unretained

ne devient pas responsable

- (void) dealloc {[myTableView setDelegate:nil];[myTableView setDataSource:nil];

}

utilisé pour éviter les deadlocks

Page 24: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

__weak

ne devient pas responsable

utilisé pour éviter les deadlocks

remis à nil dès que l’objet est détruit

! disponible que depuis iOS 5.0 et OS X 10.7

- (void) testWeak {id newObject = [NSObject new];__weak id value = newObject;newObject = nil;assert(value == nil);

}

Page 25: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

@property (strong) id x; // __strong , a.k.a retain

@property (unsafe_unretained) id y; // __unsafe_unretained , a.k.a assign

@property (weak) id z; // __weak

Page 26: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

blocks

Page 27: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

^{ ... }

ARC

dispatch_block_t block;

if ( ... ) {

} else {

}

block();

;block =

^{ ... } ;block =

Page 28: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

myObj = [[MyObject alloc] initWithBlock:^{

MyObject* myObj;int myIvar;

MyClass* weakSelf = self;

weakSelf->myIvar);

MyClass.h

MyClass.m__block __unsafe_unretained

}];NSLog(@"%i",

Page 29: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

__weak

MyObject* strongSelf = weakSelfif (strongSelf)

ARC

myObj = [[MyObject alloc] initWithBlock:^{

MyObject* myObj;int myIvar;

MyClass* weakSelf = self;

myIvar);

MyClass.h

MyClass.m

}];NSLog(@"%i", strongSelf->

Page 30: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

Core Foundation

Page 31: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

CFArrayRef) [[NSArray alloc] init];

NSDictionary*) CFDictionaryCreate(...);

NSString*) myCFString;

ARC

NSDictionary* dict = (

NSString* myNSString = ( __bridge

__bridge_transfer

__bridge_retainedCFArrayRef aray = (

Page 32: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

Project configuration

Page 33: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

Page 34: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

-fno-objc-arc-fobjc-arc

Page 35: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

- (NSString*) copyRightLicense {return license;

}

objc_release ( l );

- (void) checkLicense {NSString* l = [license copyRightLicense];...

}

Non-ARC compiled

ARC compiled

Page 36: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

- (void) checkLicense {

...License* l = [License createLicense]

ARC

+ (License*) createLicense {return [[self alloc] init];

}

objc_release ( l );}

Non-ARC compiled

ARC compiled__strong objc_retain ( ;)

Page 37: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARC

+ (License*) createLicense

- (NSString*) copyRightLicense

NS_RETURNS_RETAINED

NS_RETURNS_NOT_RETAINED ;

;

Page 39: CocoaHeads Rennes #9 : Gestion mémoire, du débutant à l'expert

ARCpour ou contre ?