2016-08-12 5 views
0

В моем проекте, у меня есть функция, как это:обертывания и разворачивают с NSValue

- (void)doSomething:(NSError**)error { 
... 
} 

Мне нужно вызвать эту функцию в другом потоке, используя функцию performSelector:onThread:withObject:waitUntilDone:, что-то вроде этого:

[self performSelector:@selector(doSomething:) onThread:anotherThread withObject:??? waitUntilDone:NO]; 

Но параметр функции имеет тип NSError**. Я рассматриваю refactor тип параметра функции -(void)doSomething: от NSError** до NSValue* и передать NSValue* тип в качестве аргумента.

Это означает, что мне нужно обернуть &error (который имеет тип NSError **) в NSValue и передать его в качестве аргумента и развернуть его позже. Как обернуть & развернуть NSError** с NSValue класс?

+1

Зачем вам нужно обернуть 'NSError' в' NSValue'? – rmaddy

+0

Я хочу обернуть «NSError **» и передать завернутый NSValue в качестве сегмента, а затем вызвать performSelector: withObject, –

+1

1) Зачем вам нужно обернуть 'NSError'' NSValue', чтобы передать его 'performSelector : withObject: '? Его не нужно обертывать. 2) Зачем вам нужно использовать 'performSelector: withObject:'? Всегда есть лучший способ.Я предлагаю обновить свой вопрос с более подробной информацией о том, что вам действительно нужно сделать, чтобы люди могли предложить лучший совет. – rmaddy

ответ

0

Я думаю, вы можете использовать NSValue's valueWithPointer: и pointerValue. Но я хотел бы предложить вам использовать что-то другое, как НОД запустить блок асинхронно вместо того чтобы изменить подпись вашего метода, чтобы соответствовать ограничениям performSelector:

dispatch_async(anotherQueue, ^{ 
    [self doSomething:&error]; 
}); 

Также this question имеет несколько идей о том, как подойти к этой проблеме, если вы действительно хотите пойти по этому пути.

+0

Спасибо, но мне нужно использовать переменную 'otherThread', поэтому мне нужно использовать performSelector: onThread: WithObject –

0

Вам необходимо пересмотреть свой подход к этой проблеме. Ваш метод:

- (void)doSomething:(NSError**)error 

следует стандартной схеме Objective-C прохождения адреса из NSError * переменных так, что этот метод может установить переменный, чтобы вернуть ошибку.

Если вы пытаетесь использовать этот метод асинхронно, независимо от того, используете ли вы performSelector:onThread:withObject:waitUntilDone:, когда пытаетесь или используете GCD (как предложил Фелипе Кириано), вы должны быть осторожны - переменная, адрес которой вы проходите, должен существовать как время, асинхронный вызов выполняется, и даже после того, как вы указали, что вам нужно выяснить, когда асинхронный вызов завершен, чтобы вы могли проверить, задана ли эта переменная ...

Обычный способ решения таких проблем заключается в использовании блока завершения, который метод асинхронного вызова вызывает, когда он завершен, передавая любые результаты - NSError * в вашем случае. Например, вы могли бы написать метод:

- (void) doSomethingAsyncAndThen:(void (^)(NSError *))completionBlock 
{ 
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), 
        ^{ 
        NSError *error = nil; 
        [self doSomething:&error]; 
        completionBlock(error); 
        }); 
} 

и называют это нравится:

[self doSomethingAsyncAndThen:^(NSError *error) { NSLog(@"error: %@", error); }]; 

если вы хотите сделать что-то другое, чем просто NSLog результат.

НТН