memory managment in i os (1)

28
Управление памятью в iOS - Лучшие Практики

Upload: it-park

Post on 26-Dec-2014

526 views

Category:

Documents


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Memory managment in i os (1)

Управление памятью в iOS -

Лучшие Практики

Page 2: Memory managment in i os (1)

2

Почему об этом столько говорят?

• Не полностью автоматоматическое• Не полностью ручное

• Нет Garbage Collector под iOS

Page 3: Memory managment in i os (1)

Подсчёт ссылок•Alloc (+1) 1•Retain (+1) 2•Release (-1) 1•Release (-1) 0•Release ПАДЕНИЕ!

Page 4: Memory managment in i os (1)

Владение объектом• Кто сделал init, тот и папа

SomeObject *iOwnThis = [[SomeObject alloc] init]; [iOwnThis doYourThing];

[iOwnThis release];

• Временный объектNSNumber* value = [NSNumber numberWithFloat:14.78];

Передача владения

- (void) setName: (NSString*)str {

[name release];

name = [str retain];

}

Page 5: Memory managment in i os (1)

5

Договорённость по именованию

• Чтобы создать объект и стать его владельцем надо использовать один из следующих методов–alloc–new–copy–mutableCopy

Page 6: Memory managment in i os (1)

6

dealloc

•Отвечает за освобождение памяти• Внутри нужно вызвать [super dealloc]• Не рекомндуется вкладывать другую

функциональность•Можно сделать [obj release] если obj равен nil• Этот метод нигде кроме [super dealloc] не

должен вызываться вручную

Page 7: Memory managment in i os (1)

7

Property в Objective C

• Writability–readonly–readwrite

• Setter semantic–assign–copy–retain

• Atomicity–atomic–nonatomic

Page 8: Memory managment in i os (1)

8

Property

•Обьявление

@property (writability, setter, atomicity) type *name;@synthesize name = _name;

•Использование

object.propertyName = newValue;value = object.propertyName;

Page 9: Memory managment in i os (1)

9

Assign property- (void)setSomeValue:(SomeVariable*)aSomeVariableValue

{

someValue = aSomeVariableValue;

}

Page 10: Memory managment in i os (1)

10

Retain property- (void)setSomeInstance:(SomeClass *)aSomeInstanceValue

{

if (someInstance == aSomeInstanceValue)

return;

SomeClass *oldValue = someInstance;

someInstance = [aSomeInstanceValue retain];

[oldValue release];

}

Page 11: Memory managment in i os (1)

11

Copy property- (void)setStringValue:(NSString *)aString

{

if (stringValue == aString)

return;

NSString *oldValue = stringValue;

stringValue = [aString copy];

[oldValue release];

}

Page 12: Memory managment in i os (1)

NSAutoreleasePool

• *** __NSAutoreleaseNoPool(): Object autoreleased with no pool in place — just leaking• В других потоках надо создавать отдельно

• В него добавляются временные объекты• Автоматически создаётся в

главном потоке

Page 13: Memory managment in i os (1)

13

AutoreleasePool в главном потоке

int main(int argc, char *argv[]) {

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

int retVal = UIApplicationMain(argc, argv, nil, nil);

[pool release];

return retVal;

}

int main(int argc, char *argv[])

{

@autoreleasepool {

return UIApplicationMain(argc, argv, nil, nil);

}

}

Page 14: Memory managment in i os (1)

14

Распространённые ошибки- (void) reset

{

NSNumber * zero = [[NSNumber alloc] initWithInteger:0];

[self setCount:zero];

}

Исправленная версия- (void) reset{ NSNumber * zero = [[NSNumber alloc] initWithInteger:0]; [self setCount:zero]; [zero release];}

Page 15: Memory managment in i os (1)

15

Распространённые ошибки• - (void) reset

• {

• NSNumber * zero = [NSNumber numberWithInteger:0];

• [self setCount:zero];

• [zero release];

• }

•Исправленная версия•

- (void) reset• {• NSNumber * zero = [NSNumber numberWithInteger:0];• [self setCount:zero];• }

Page 16: Memory managment in i os (1)

16

Возвращение Property• - (NSNumber*) count

• {

• [count retain];

• return count;

• }

•Исправленная версия• - (NSNumber*) count• {• return count;• }

Page 17: Memory managment in i os (1)

17

Обращение к Property• - (void) reset

• {

• NSNumber * zero = [NSNumber numberWithInteger:0];

• self.count = zero;

• //Разные вещи!!!

• count = zero;

• }

Page 18: Memory managment in i os (1)

18

Добавление в массив передаёт владение объектом

• - (NSArray *)getPeople {

• NSMutableArray *array = [[NSMutableArray alloc] init];

• for (int i = 0; i < 10; i++) {

• Person *p = [[Person alloc] init];

• [array addObject:p];

• }

• return array;

• }

• Исправленная версия

• - (NSArray *)getPeople {

• NSMutableArray *array = [[NSMutableArray alloc] init];

• for (int i = 0; i < 10; i++) {

• Person *p = [[Person alloc] init];

• [array addObject:p];

• [p release];

• }

• return array;

• }

Page 19: Memory managment in i os (1)

19

Перезапись без release- (void) leak

{

name = [[NSString alloc] initWithFormat:@"%@-%@",@"John",@"Paul"];

name = @"Chris";

}

Исправленная версия- (void) leak

{

name = [[NSString alloc] initWithFormat:@"%@-%@",@"John",@"Paul"];

[name release];

name = @"Chris";

}

Page 20: Memory managment in i os (1)

20

Повисший указатель- (id) init{

if (self = [super init]) {

count = [NSNumber numberWithInteger:0];

}

return self;

}

- (void) logCount

{

NSLog(@"Count is %@",count);

}

Page 21: Memory managment in i os (1)

21

Исправленная версия - (id) init{ if (self = [super init]) { count = [NSNumber numberWithInteger:0]; [count retain]; } return self;}

- (void) logCount { NSLog(@"Count is %@",count);}

- (void) dealloc { [count release];}

Page 22: Memory managment in i os (1)

22

Обнуление делегатов- (void)dealloc

{

self.someObject.delegate = nil;

self.someObject = nil;

[super dealloc];

}

Page 23: Memory managment in i os (1)

23

Memory Warning

• Автоматически делаетсяsetView:nil неактивным ViewControllers

• Чистим ресурсы в приложении- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application

{

[[ImageCache sharedImageCache] removeAllImagesInMemory];

}

• Подписываемся на Notification

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

[center addObserver:self

selector:@selector(whatever:)

name:UIApplicationDidReceiveMemoryWarningNotification

object:nil];

Page 24: Memory managment in i os (1)

Устранение ошибок памяти

•Используйте LLVM / Clang статический анализатор•Не overthink управления памятью•Всегда используйте методы доступа; объявить

доступа с использованием свойств•Инструмент Инструменты Утечки

Page 25: Memory managment in i os (1)

EXC_BAD_ACCESS

• Поставтье брейкпойнт в программе и шагайте до падения• Тактика закомменть и попробуй падает ли• NSZombieEnabled - при падении можно увидеть к

объекту какого типа было обращение и какой селектор был вызван

Page 26: Memory managment in i os (1)

26

Clang Static Analyzer

Page 27: Memory managment in i os (1)

27

Автоматический подсчёт ссылок

• По сути - автоматическое исправление всех замечаний найденных статическим анализатором• Не сборка мусора!• Не может решить всех проблем связанных с

циклическими ссылками

Page 28: Memory managment in i os (1)

28

Property в ARC

• strong - аналог retain. Проперти является владельцем объекта по ссылке•weak - слабая ссылка без владения.

Автоматически ставиться в nil когда объект по ссылке удаляется.• unsafe_unretained - синоним assign. Надо

использовать вместо weak в iOS 4• copy - всё попрежнему, объект копируется и

создаётся сильная связь