Я пытаюсь использовать метод из класса, который я загрузил где-то. Метод выполняется в фоновом режиме, пока выполнение программы продолжается. Я не хочу, чтобы выполнение программы продолжалось до тех пор, пока этот метод не завершится. Как мне это сделать?Как дождаться окончания потока в Objective-C
ответ
Я бы предложил включить вызов метода класса в свой собственный метод и установить логическое значение после его завершения. Для например:
BOOL isThreadRunning = NO;
- (void)beginThread {
isThreadRunning = YES;
[self performSelectorInBackground:@selector(backgroundThread) withObject:nil];
}
- (void)backgroundThread {
[myClass doLongTask];
// Done!
isThreadRunning = NO;
}
- (void)waitForThread {
if (! isThreadRunning) {
// Thread completed
[self doSomething];
}
}
Как вы хотите обрабатывать ожидания до вас: Возможно, опрос с [NSThread sleepForTimeInterval: 1] или аналогичный, или отправив сообщение и настраивает каждый цикл выполнения.
Мое первое желание - не делать то, что вы предлагаете. Техника, которую я использовал ранее, - это дать потоку селектор методу в исходном объекте (который находится в основном потоке). Когда второй поток запущен, основной поток продолжает выполняться, но на дисплее отображает индикатор занятости. Это позволяет при необходимости взаимодействовать с пользователем.
Когда вторая нить заканчивается, перед ее выключением она вызывает селектор в основном потоке. Метод, который ссылается на селектор, затем удаляет индикатор занятости с дисплея и сообщает основному потоку обновляться, собирая все данные, которые генерировал второй поток.
Я успешно использовал это приложение, которое обращается к веб-службе (во втором потоке), а затем обновляет отображение после возвращения данных без его блокировки. Это значительно улучшает работу пользователя.
Это хорошая система для обновлений пользовательского интерфейса; они могут быть болью. – v01d
Используйте NSOperationQueue, как это
(из памяти так что простите любые незначительные ошибки - вы получите основную идею):
// ivars
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
// count can be anything you like
[opQueue setMaxConcurrentOperationCount:5];
- (void)main
{
[self doStuffInOperations];
}
// method
- (void)doStuffInOperations
{
// do parallel task A
[opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"a"] autorelease]];
// do parallel task B
[opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"b"] autorelease]];
// do parallel task C
[opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"c"] autorelease]];
[opQueue waitUntilAllOperationsHaveFinished];
// now, do stuff that requires A, B, and C to be finished, and they should be finished much faster because they are in parallel.
}
- (void)doSomething:(id)arg
{
// do whatever you want with the arg here
// (which is in the background,
// because all NSOperations added to NSOperationQueues are.)
}
Я знаю, что я не задавал этот вопрос, но это было то, что я искал с помощью своего приложения, потому что у меня были условия гонки, и я знал, что это потому, что я мог быстрее нажимать код, чтобы закончить, таким образом, состояние частичной нагрузки на представления , Это решило мою проблему большое время. Так что спасибо вам, сэр, я чувствую, что это должно быть отмечено как истинный ответ, потому что он не использует работу и включает потокобезопасное кодирование с библиотекой ios. – Rob
Во-вторых, что Роб сказал, это именно то, что я искал тоже! – AdamM
@AdamM - ознакомьтесь с другим ответом, который я разместил сегодня. Это гораздо более чистый способ сделать это, и GCD поддерживается для всех iOS 4 и выше. Одним из важных преимуществ этого способа является то, что вы не получите сбоев, когда объекты будут освобождены из-под вас, потому что GCD автоматически сохраняет и освобождает весь объект, который вы ссылаетесь. – jpswain
Вот еще один способ сделать это с помощью НОД:
- (void)main
{
[self doStuffInOperations];
}
- (void)doStuffInGCD
{
dispatch_group_t d_group = dispatch_group_create();
dispatch_queue_t bg_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(d_group, bg_queue, ^{
[self doSomething:@"a"];
});
dispatch_group_async(d_group, bg_queue, ^{
[self doSomething:@"b"];
});
dispatch_group_async(d_group, bg_queue, ^{
[self doSomething:@"c"];
});
// you can do this to synchronously wait on the current thread:
dispatch_group_wait(d_group, DISPATCH_TIME_FOREVER);
dispatch_release(d_group);
NSLog(@"All background tasks are done!!");
// **** OR ****
// this if you just want something to happen after those are all done:
dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{
dispatch_release(d_group);
NSLog(@"All background tasks are done!!");
});
}
- (void)doSomething:(id)arg
{
// do whatever you want with the arg here
}
Мой метод, чтобы проверить, если задача может работать (если фоновый поток завершается), и если он не может работать, то я использую НОД, чтобы попробовать еще раз после задержки:
- (void)doSomething
{
if (/* is the other thread done yet? */) {
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self doSomething];
});
return;
}
// do something
}
Несколько технических способов синхронизации многопотоков, таких как NSConditionLock
(mutex-lock), NSCondition
(семафор). Но они являются общим знанием программирования для других языков (java ...), кроме объектива-c. Я предпочитаю, чтобы ввести run loop
(специальный в какао) осуществлять нить присоединиться:
NSThread *A; //global
A = [[NSThread alloc] initWithTarget:self selector:@selector(runA) object:nil]; //create thread A
[A start];
- (void)runA
{
[NSThread detachNewThreadSelector:@selector(runB) toTarget:self withObject:nil]; //create thread B
while (1)
{
if ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) //join here, waiting for thread B
{
NSLog(@"thread B quit...");
break;
}
}
}
- (void)runB
{
sleep(1);
[self performSelector:@selector(setData) onThread:A withObject:nil waitUntilDone:YES modes:@[NSDefaultRunLoopMode]];
}
В таких случаях я обычно используя класс NSCondition.
//this method executes in main thread/queue
- (void)waitForJob
{
id __weak selfWeak = self;
NSCondition *waitHandle = [NSCondition new];
[waitHandle lock];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[selfWeak doSomethingLongtime];
[waitHandle signal];
});
//waiting for background thread finished
[waitHandle waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]];
}
- 1. Как дождаться окончания потока до продолжения
- 2. Как дождаться окончания потока трубопроводов? (Nodejs)
- 3. Многопоточность WinApi C: как дождаться окончания потока?
- 4. Как дождаться окончания потока до продолжения программы
- 5. Android, как дождаться окончания потока и уведомления?
- 6. Как дождаться окончания потока ядра Linux (kthread)?
- 7. Сделать Android MainActivity дождаться окончания потока
- 8. Как дождаться окончания аниматора?
- 9. Как дождаться окончания загрузки?
- 10. Как дождаться окончания потока, прежде чем запускать больше в Java
- 11. Как дождаться окончания списка тем? (Python)
- 12. Как дождаться окончания команды системы
- 13. Как дождаться окончания всех запросов
- 14. Как дождаться окончания вложенного forkjoin?
- 15. Как дождаться окончания вызова функции в Swift
- 16. Как дождаться окончания анимации в viewDidDisappear?
- 17. Как дождаться окончания анимации в angular.js
- 18. Выполнить AutoIt и дождаться окончания
- 19. Rspec должен дождаться окончания нитей
- 20. Volley and Fragments - как дождаться окончания запроса
- 21. Как дождаться окончания всех потоков, используя ExecutorService?
- 22. Как дождаться окончания загрузки с помощью Webdriver
- 23. Как я могу дождаться окончания загрузки?
- 24. Как дождаться окончания выполнения перед следующей строкой
- 25. Как я могу дождаться окончания указанного «xterm»?
- 26. Сделать фрагмент, чтобы дождаться окончания темы
- 27. Force mongoose.save callback, чтобы дождаться окончания записи
- 28. Консоль Linux - начать процесс и дождаться окончания
- 29. Мне нужен мой экран, чтобы дождаться окончания потока до того, как его выталкивают
- 30. Как дождаться завершения потока перед продолжением?
Я сделал это, и он работает, но также предотвращает отображение HUD. –
Вы можете использовать NSTimer для опроса и сохранения обновлений пользовательского интерфейса. Все зависит от того, что вам нужно. Для простой задачи, а затем обновить ответ Дерека будет более аккуратным и менее хлопотным. – v01d
Для игрового движка или чего-то большего в реальном времени таймер может быть уже на месте. Затем, отправляя поток и забывая о нем, может быть больше, что вам нужно. – v01d