Определить конец executeSelectorInBackground: withObject: - PullRequest
4 голосов
/ 23 марта 2011

В моем приложении iOS есть асинхронный запрос к серверу:

[self performSelectorInBackground:@selector(doSomething) withObject:nil];

Как я могу определить конец этой операции?

Ответы [ 4 ]

15 голосов
/ 23 марта 2011

Поместить вызов в конец метода doSomething?!

- (void)doSomething {
    // Thread starts here

    // Do something

    // Thread ends here
    [self performSelectorOnMainThread:@selector(doSomethingDone) withObject:nil waitUntilDone:NO];
}
1 голос
/ 23 марта 2011

Если вы просто хотите знать, когда он закончится (и не хотите передавать много данных обратно - в этот момент я бы порекомендовал делегата), вы можете просто опубликовать уведомление в центре уведомлений.

[[NSNotificationCenter defaultCenter] postNotificationName:kYourFinishedNotificationName object:nil];

в ваших контроллерах view метод viewDidLoad add:

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(yourNotificationListenerMethod:)
                                                 name:kYourFinishedNotificationName
                                               object:nil];

и в dealloc добавьте:

[[NSNotificationCenter defaultCenter] removeObserver:self];
0 голосов
/ 06 декабря 2014

У меня есть общий обработчик фона, который я создал, чтобы решить эту проблему.Только первый метод является общедоступным, поэтому его можно использовать повсюду.Обратите внимание, что все параметры обязательны.

+(void) Run: (SEL)sel inBackground: (id)target withState: (id)state withCompletion: (void(^)(id state))completionHandler       // public
{
    [(id)self performSelectorInBackground: @selector(RunSelector:) withObject: @[target, NSStringFromSelector(sel), state, completionHandler]];
}

+(void) RunSelector: (NSArray*)args
{
    id target = [args objectAtIndex: 0];
    SEL sel = NSSelectorFromString([args objectAtIndex: 1]);
    id state = [args objectAtIndex: 2];
    void (^completionHandler)(id state) = [args objectAtIndex: 3];
    [target performSelector: sel withObject: state];
    [(id)self performSelectorOnMainThread: @selector(RunCompletion:) withObject: @[completionHandler, state] waitUntilDone: true];
}

+(void) RunCompletion: (NSArray*)args
{
    void (^completionHandler)(id state) = [args objectAtIndex: 0];
    id state = [args objectAtIndex: 1];
    completionHandler(state);
}

Вот пример того, как он называется:

NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
__block BOOL done = false;
[Utility Run: @selector(RunSomething:) inBackground: self withState: dic withCompletion:^(id state) {
        done = true;
    }];
0 голосов
/ 23 марта 2011

Возможно, вы захотите, чтобы ваш селектор doSomething отправил сообщение обратно, когда он завершит свою работу. То, что происходит на executeSelectorInBackground, является внутренним по отношению к API, и если вы хотите больше контроля, вы можете использовать performSelector:onThread:withObject:waitUntilDone: и периодически проверять isFinished в переданном потоке. Я уверен, что вы больше обеспокоены завершением doSomething, чем самим потоком, хотя просто отправьте сообщение оттуда.

...