Как я могу отменить операцию NSO в том же потоке, что и операция? - PullRequest
0 голосов
/ 24 января 2012

Когда я отменяю операцию NSOperation (когда пользователь нажимает кнопку), метод отмены вызывается из основного потока, но, очевидно, операция выполняется в другом потоке. Поэтому, чтобы избежать условий гонки, когда я изменяю _isExecuting и _isFinished, я думаю, что отмена (или, по крайней мере, ее логика) должна вызываться из того же потока, что и операция NSOperation. Кроме того, когда пользователь отменяет его, несколько файлов удаляются, и это занимает время. Поскольку отмена вызывается из основного потока, все приложение на некоторое время перестает отвечать, что ужасно.

Как выполнить код отмены в том же потоке, что и текущая операция NSO?

Я попытался это отменить (аналогично тому, что я видел в ASIHTTPRequest):

if (_operationThread) {
    [self performSelector:@selector(cancelOnRequestThread) onThread:_operationThread withObject:nil waitUntilDone:NO];
} else {
    [self cancelOnRequestThread];
}

И _operationThread устанавливается в методе start с использованием: _operationThread = [NSThread currentThread];

Но это не работает.

Любая идея или предложение?

Примечание: я использую параллельные операции, поэтому я использую start вместо main.

Большое спасибо за помощь. Рикардо.

1 Ответ

4 голосов
/ 24 января 2012

Это нормально, чтобы вызвать отмену на NSOperation из основного потока. Метод отмены является потокобезопасным.

Это не должно вызывать каких-либо блокировок в вашем основном потоке, потому что сам метод cancel не должен выполнять какую-либо работу. Если вы переопределили метод отмены вашей операции для удаления файлов и т. Д., То это неправильный подход. Вы не должны переопределять метод cancel, вместо этого просто проверяйте метод isCancelled в регулярных точках основного метода операции (например, внутри любых замкнутых циклов), а затем возвращайтесь из раннего main, если isCancelled возвращает YES, что затем отменяет операцию на том же самом нить как и остальная часть исполнения.

Если вы уже реализовали это, и у вас все еще есть проблемы с производительностью, возможно ли, что ваша операция вообще не работает в фоновом потоке? Например, если вы добавили его в очередь, возвращаемую [NSOperationQueue mainQueue], то он фактически выполняется в главном потоке приложения.

...