Насколько я понимаю, есть несколько способов отправки задач для выполнения в потоках. Самые распространенные из них:
1) performSelector: withObject: afterDelay:
2) performSelectorOnMainThread: withObject: waitUntilDone:
3) performSelectorInBackground: withObject:
4) [NSThread detachNewThreadSelector: toTarget: withObject:]
Мой первый вопрос: в чем разница между 1) и 2), помимо очевидных различий в параметрах? Действительно ли они оба работают в основном потоке (чей пул автозапуска был автоматически создан в main.m)? Я только что прочитал из чьей-то публикации в Stackoverflow, что метод 1) фактически работает в новом потоке, поэтому для его метода выбора должен быть создан пул автозапуска. Это правильно? Я много использовал 1), в основном чтобы воспользоваться параметром задержки, но я никогда не создавал для них пул автозапуска. Ничего катастрофического не произошло.
Далее, 3) и 4) оба выполняют задачи в отдельном потоке. Я слышал, что элементы пользовательского интерфейса никогда не должны выполняться в этих потоках, но я не понимаю, что именно является пользовательским интерфейсом. Я пытался написать код, чтобы в основном воспроизводить повторяющуюся анимацию загрузки, пока табличное представление запускается модально из контроллера навигации. Затем анимация останавливается в методе viewDidLoad контроллера tableview. Изначально я просто вставил код для запуска анимации над строками кода, которые запускают модальное представление. Что случилось, так это то, что анимацию так и не проиграли.
[[self loadingView] playAnimation];
SettingsViewController *menus = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil];
MyNavigationController *navController = [[MyNavigationController alloc] initWithRootViewController:menus];
[menus setParent:navController];
[navController setDelegate:self];
menus.mainViewController = self;
[self presentModalViewController:navController animated:YES];
[navController release];
[menus release];
Затем я попробовал следующее, и это сработало ...
[NSThread detachNewThreadSelector:@selector(settingsOpeningThread) toTarget:self withObject:nil];
[[self loadingView] playAnimation];
- (void) settingsOpeningThread {
NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];
SettingsViewController *menus = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil];
MyNavigationController *navController = [[MyNavigationController alloc] initWithRootViewController:menus];
[menus setParent:navController];
[navController setDelegate:self];
menus.mainViewController = self;
[self presentModalViewController:navController animated:YES];
[navController release];
[menus release];
[apool release];
}
Анимация будет воспроизводиться до тех пор, пока не будет полностью запущено представление SettingsViewController. Но считается ли запуск таких модальных представлений «пользовательским интерфейсом», и его следует избегать? Также я получаю некоторые странные ошибки утечки памяти в инструментах каждый раз, когда запускается модальное представление. Но это из одной из тех «Системных библиотек», которые, как мне сказали, очень трудно отлаживать. Что здесь может быть не так?
Извините за досадно длинный пост. Любая помощь будет оценена по достоинству!