Проблемы с вызываемым NSOperationQueue и dealloc и сбоем приложения - PullRequest
1 голос
/ 03 сентября 2010

Я создал NSOperation в очереди следующим образом:

ImageLoadingOperation *operation = [[ImageLoadingOperation alloc] initWithImageURL:url target:self action:@selector(didFinishLoadingImageWithResult:)];
[operationQueue addOperation:operation];
[operation release];

И это работает нормально, но если представление прерывается до завершения операции, приложение вылетает с "EXC_BAD_ACCESS"

Я пытался отменить очередь операций, вызвав метод cancelAllOperations, но поскольку он уже выполняется, он не предотвращает сбой приложения.Документы говорят, что, если операция выполняется, она должна определить, была ли она отменена, и ответить соответствующим образом, но не слишком уверена, как бы я это реализовал?

Есть идеи?

Ответы [ 3 ]

1 голос
/ 03 сентября 2010

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

Мое решение - вы можете сохранить представление перед вызовом операции.И затем, когда операция заканчивается, вы освобождаете представление.

- (void)longTask {
   [self retain];
}

- (void)longTaskDidFinish {
   // do something if you want
   [self release];
}
0 голосов
/ 16 ноября 2015

Вы можете сохранить представление до вызова обратного вызова операции, как упоминалось выше vodkhang.Но это продлевает срок службы представления без необходимости, потому что, поскольку представление выскочило, вы больше не хотите, чтобы операция продолжалась.
Вот эскиз того, что вы должны сделать для ответа на команду отмены:

- (void)start{
    if(self.isCancelled){
       [self markAsFinished];
       return;
    }
    //start your task asynchronously
}


//If you want to cancel the downloading progress immediately, implement your own 'cancel' method
- (void)cancel{
    [super cancel];
    if(self.isExecuting){
       {
          ......
          cancel load process
          ......
       }
       [self markAsFinished];
    }
}

- (void)markAsFinished{
    ......
    change 'finished' to YES'  generate KVO notifications on this key path
    change 'executing' to 'YES'; generate KVO notification on this key path
    ...... 
}

Этот эскиз основан на сетевой библиотеке ASIHTTPRequest, и есть официальное руководство о том, как вы должны ответить на команду отмены.

0 голосов
/ 24 октября 2015

Вам придется либо переопределить операцию «отмена» в своем классе ImageLoadingOperation, либо сделать так, чтобы ваша ImageLoadingOperation добавила себя в качестве наблюдателя KVO в свойство «отменено».Там - вы можете разумно отменить свою операцию таким образом, чтобы она не потерпела крах.

Также, если ваша ImageLoadingOperation выполняется в фоновом режиме, было бы разумнее как-то отложить ваш доступ к представлениям для основного потока(где все рисование происходит).Вы можете использовать dispatch_sync (dispatch_get_main_queue (), ^ {});или даже executeSelectorOnMainThread для фактического доступа к связанному представлению.

Видите ли, весь смысл использования очереди операций состоит в том, чтобы удалить зависимости и позволить вещам работать параллельно, но ваша операция должна синхронизироваться с системой представленияизменения, и это должно быть разработано для полноты и надежности.

...