memory managment in i os
TRANSCRIPT
![Page 1: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/1.jpg)
Управление памятью в iOS -
Лучшие Практики
![Page 2: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/2.jpg)
2
Почему об этом столько говорят?
• Не полностью автоматоматическое• Не полностью ручное
• Нет Garbage Collector под iOS
![Page 3: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/3.jpg)
Подсчёт ссылок•Alloc (+1) 1•Retain (+1) 2•Release (-1) 1•Release (-1) 0•Release ПАДЕНИЕ!
![Page 4: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/4.jpg)
Владение объектом• Кто сделал 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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/5.jpg)
5
Договорённость по именованию
• Чтобы создать объект и стать его владельцем надо использовать один из следующих методов–alloc–new–copy–mutableCopy
![Page 6: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/6.jpg)
6
dealloc
•Отвечает за освобождение памяти• Внутри нужно вызвать [super dealloc]• Не рекомндуется вкладывать другую
функциональность•Можно сделать [obj release] если obj равен nil• Этот метод нигде кроме [super dealloc] не
должен вызываться вручную
![Page 7: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/7.jpg)
7
Property в Objective C
• Writability–readonly–readwrite
• Setter semantic–assign–copy–retain
• Atomicity–atomic–nonatomic
![Page 8: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/8.jpg)
8
Property
•Обьявление
@property (writability, setter, atomicity) type *name;@synthesize name = _name;
•Использование
object.propertyName = newValue;value = object.propertyName;
![Page 9: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/9.jpg)
9
Assign property- (void)setSomeValue:(SomeVariable*)aSomeVariableValue
{
someValue = aSomeVariableValue;
}
![Page 10: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/10.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/11.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/12.jpg)
NSAutoreleasePool
• *** __NSAutoreleaseNoPool(): Object autoreleased with no pool in place — just leaking• В других потоках надо создавать отдельно
• В него добавляются временные объекты• Автоматически создаётся в
главном потоке
![Page 13: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/13.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/14.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/15.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/16.jpg)
16
Возвращение Property• - (NSNumber*) count
• {
• [count retain];
• return count;
• }
•Исправленная версия• - (NSNumber*) count• {• return count;• }
![Page 17: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/17.jpg)
17
Обращение к Property• - (void) reset
• {
• NSNumber * zero = [NSNumber numberWithInteger:0];
•
• self.count = zero;
• //Разные вещи!!!
• count = zero;
• }
![Page 18: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/18.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/19.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/20.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/21.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/22.jpg)
22
Обнуление делегатов- (void)dealloc
{
self.someObject.delegate = nil;
self.someObject = nil;
[super dealloc];
}
![Page 23: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/23.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/24.jpg)
Устранение ошибок памяти
•Используйте LLVM / Clang статический анализатор•Не overthink управления памятью•Всегда используйте методы доступа; объявить
доступа с использованием свойств•Инструмент Инструменты Утечки
![Page 25: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/25.jpg)
EXC_BAD_ACCESS
• Поставтье брейкпойнт в программе и шагайте до падения• Тактика закомменть и попробуй падает ли• NSZombieEnabled - при падении можно увидеть к
объекту какого типа было обращение и какой селектор был вызван
![Page 26: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/26.jpg)
26
Clang Static Analyzer
![Page 27: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/27.jpg)
27
Автоматический подсчёт ссылок
• По сути - автоматическое исправление всех замечаний найденных статическим анализатором• Не сборка мусора!• Не может решить всех проблем связанных с
циклическими ссылками
![Page 28: Memory managment in i os](https://reader036.vdocuments.site/reader036/viewer/2022062606/558984dbd8b42a49748b4644/html5/thumbnails/28.jpg)
28
Property в ARC
• strong - аналог retain. Проперти является владельцем объекта по ссылке•weak - слабая ссылка без владения.
Автоматически ставиться в nil когда объект по ссылке удаляется.• unsafe_unretained - синоним assign. Надо
использовать вместо weak в iOS 4• copy - всё попрежнему, объект копируется и
создаётся сильная связь