Читаем iOS. Приемы программирования полностью

class NSCFString autoreleased with no pool in place — just leaking

*** __NSAutoreleaseNoPool: Object 0x5b2ca30 of

class NSPathStore2 autoreleased with no pool in place — just leaking

*** __NSAutoreleaseNoPool: Object 0x5b205c0 of

class NSPathStore2 autoreleased with no pool in place — just leaking

*** __NSAutoreleaseNoPool: Object 0x5b2d650 of

class UIImage autoreleased with no pool in place — just leaking


Эти данные свидетельствуют о том, что созданный нами автоматически высвобождаемый экземпляр UIImage приводит к утечке памяти. Более того, утечку вызывают и экземпляр класса NSString под названием FilePath, а также другие объекты, которые в обычной ситуации спокойно высвободились бы. Дело в том, что при создании потока мы забыли первым делом выделить и инициализировать автоматически высвобождаемый пул — именно первым делом. Далее приведен правильный код. Можете сами его протестировать и убедиться, что никаких утечек не возникает:


— (void) autoreleaseThread:(id)paramSender{


@autoreleasepool {

NSBundle *mainBundle = [NSBundle mainBundle];

NSString *filePath = [mainBundle pathForResource:@"AnImage"

ofType:@"png"];


UIImage *image = [UIImage imageWithContentsOfFile: filePath];


/* Делаем что-то с изображением. */

NSLog(@"Image = %@", image);

}


}

— (void)viewDidLoad {


[super viewDidLoad];

[NSThread detachNewThreadSelector:@selector(autoreleaseThread:)

toTarget: self

withObject: self];

}

7.16. Активизация фоновых методов

Постановка задачи

Необходимо найти простой способ создания потоков так, чтобы с потоками не приходилось работать напрямую.

Решение

Воспользуйтесь методом экземпляра performSelectorInBackground: withObject:, относящимся к классу NSObject:


— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{


[self performSelectorInBackground:@selector(firstCounter)

withObject: nil];


[self performSelectorInBackground:@selector(secondCounter)

withObject: nil];


[self performSelectorInBackground:@selector(thirdCounter)

withObject: nil];


self.window = [[UIWindow alloc] initWithFrame:

[[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}


Методы счетчиков реализуются следующим образом:


— (void) firstCounter{


@autoreleasepool {

NSUInteger counter = 0;

for (counter = 0;

counter < 1000;

counter++){

NSLog(@"First Counter = %lu", (unsigned long)counter);

}

}


}


— (void) secondCounter{


@autoreleasepool {

NSUInteger counter = 0;

for (counter = 0;

counter < 1000;

counter++){

NSLog(@"Second Counter = %lu", (unsigned long)counter);

}

}


}


— (void) thirdCounter{


@autoreleasepool {

NSUInteger counter = 0;

for (counter = 0;

counter < 1000;

counter++){

NSLog(@"Third Counter = %lu", (unsigned long)counter);

}

}


}

Обсуждение

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже