2015-08-07 3 views
0

Я хотел бы понять, что является правильным поведением для подкласса nsoperation. У меня есть мои подклассы с разными условиями isReady. Да, я проверяю код, если операция отменена, и я действую в результате. Это отлично, когда операция выполняется. Он останавливает свою задачу, устанавливает законченное значение true и удаляется из очереди. но как насчет его зависимостей? они еще не исполняются, поэтому они остаются в NSOperationQueue в состоянии отмены навсегда.NSOperation cancel и NSOperationQueue

Должен ли я установить ready = true для отмененных операций, чтобы очередь вызывала метод запуска, который будет установлен в процессе выполнения, и немедленно завершит настройку задачи, завершенную до да?

Спасибо за помощь.

+0

Если '' '' '' '' '' '' '' '' 'будет выполняться после' a.finished == true' и 'b.ready == true' – nRewik

+0

У вас не возникла проблема. Явное поведение зависимостей. неясно, что я должен сделать для логики отмены. Если b зависит от a, a выполняет и отменяется, b также будет отменен, но готовый не может быть правдой, поэтому очередь не удалит операцию из массива. Это проблема. Теперь меня интересует логика отмены, когда операция еще не началась. Благодарю. –

+0

Какой 'cancel' вы вызываете' operationQueue.cancelAllOperations() 'или' a.cancel() '? – nRewik

ответ

1

Зависимая операция будет выполнена. Независимо от того, a отменен или нет.

Вы должны установить operation.finished==true в последнем состоянии, чтобы сделать NSOperationQueue удаляет operation.

Вы должны установить .ready==true всякий раз, когда он готов начать operation.

В жизненном цикле operation, вы должны часто проверять .cancelled когда это .cancelled == true, вы должны остановить operation и установить .finished == true.

0

Я просто справился с этой проблемой самостоятельно. Я не мог понять, почему, когда я отменил свой подкласс NSOperation, он никогда не удалялся из NSOperationQueue. Оказывается, виноват мой переопределенный метод isReady. Метод isReady проверял супер реализацию И было ли установлено свойство, чего у него не было, поэтому операция была отменена. Однако, видимо, если экземпляр NSOperation никогда не достигает состояния готовности, даже если он отменен, NSOperationQueue не удалит эту операцию до тех пор, пока не достигнет состояния готовности. Следовательно, решение - это ИЛИ ваши пользовательские условия для готовности с использованием значения свойства isCancelled. В качестве альтернативы вы можете изменить логику так, чтобы операция всегда была готова, но ничего не делайте в основном методе, если ваши условия готовности не выполняются в зависимости от вашей логики приложения.

Пример:

// for proper KVO compliance 
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key 
{ 
    NSSet *keys = [super keyPathsForValuesAffectingValueForKey:key]; 

    NSString *readyKey = NSStringFromSelector(@selector(isReady)); 
    if ([readyKey isEqualToString:key]) { 
     keys = [keys setByAddingObjectsFromArray:@[NSStringFromSelector(@selector(url)), NSStringFromSelector(@selector(isCancelled))]]; 
    } 

    return keys; 
} 

- (BOOL)isReady 
{ 
    return (this.url != nil || this.isCancelled) && super.isReady; 
} 

- (void)setUrl:(NSURL *)url 
{ 
    if (self.url == url) { 
     return; 
    } 

    NSString *urlKey = NSStringFromSelector(@selector(url)); 

    [self willChangeValueForKey:urlKey]; 

    _url = url; 

    [self didChangeValueForKey:urlKey]; 
} 

Благодаря NSHipster-х KVO article для выше KVO связанного кода.