*** __NSAutoreleaseNoPool(): Object 0x5b2c990 of

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];

}

<p>7.16. Активизация фоновых методов</p><p>Постановка задачи</p>

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

<p>Решение</p>

Воспользуйтесь методом экземпляра 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);

}

}

}

<p>Обсуждение</p>
Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Похожие книги