2016-04-02 2 views
0

В моем подклассе NSOperation я установил 4 флага, и когда операция завершает его выполнение, она не удаляется в очередь NSOperation, где она была добавлена ​​в начале, эта вещь вызывает много проблем в моем приложении. Я полагаю, что способ, которым я устанавливаю эти флаги, неверен, не могли бы вы помочь с ним. потому что я действительно трачу много времени на выявление этой проблемы.Объект NSOperation не удаляется из NSOperationQueue после выполнения

@property(assign, nonatomic) BOOL isCancelled; 
@property(nonatomic, getter=isExecuting) BOOL executing; 
@property(nonatomic, getter=isFinished) BOOL finished; 
@property(readonly, getter=isAsynchronous) BOOL asynchronous; 

//in initialisation 
- (id)initWithURL:(NSURL*)url andRaw:(NSInteger)row 
{ 
    if (![super init]) 
     return nil; 
    [self setTargetURL:url]; 

    return self; 
} 
//the way I override KVO 
- (BOOL)isExecuting 
{ 
    NSLog(@"Exec"); 
    return (self.defaultSession != nil);//it doesn't work 
} 

- (BOOL)isFinished 
{ 
    NSLog(@"Finished"); 
    return (self.defaultSession == nil); //it doesn't work, so I explicitly set the value 
} 

- (BOOL)isAsynchronous 
{ 
    return YES; 
} 

- (void)cancel 
{ 
    [super cancel]; 
    [self willChangeValueForKey:@"isExecuting"]; 
    [self willChangeValueForKey:@"isFinished"]; 
    self.isExecuting = NO; 
    self.isFinished = YES; 
    [self didChangeValueForKey:@"isFinished"]; 
    [self didChangeValueForKey:@"isExecuting"]; 

    if(self.downloadTask.state == NSURLSessionTaskStateRunning) 
     [self.downloadTask cancel]; 
    [self finish]; 
} 
- (void)finish 
{ 
    [self willChangeValueForKey:@"isExecuting"]; 
    [self willChangeValueForKey:@"isFinished"]; 
    self.defaultSession = nil; //NSURLSession 
    self.isFinished = YES; 
    [self didChangeValueForKey:@"isFinished"]; 
    [self didChangeValueForKey:@"isExecuting"]; 
} 

Спасибо заранее

EDIT: , наконец, я нашел проблему - это NSURLSession внутри очереди. Он постоянно ссылался на очередь и не позволял ему освобождаться и удаляться из NSOperationQueue.

ответ

2

Я сделал то же самое, albiet в Swift.

Есть несколько аспектов, которые я реализованы по-разному и перечислены ниже:

  • я заметил, что мы не должны переопределить отмены() метод в асинхронном операции . По умолчанию метод отмены NSOperation заключается в том, чтобы установить self.cancelled boolean в значение true.
  • self.executing должен быть установлен в true только внутри метода работы overriden start(), но не в init (не уверен, что этот wil вызывает какие-либо проблемы). Также перед установкой self.executing = true в методе start() я гарантирую, что логическое self.cancelled является ложным. Если self.cancelled = true, мы должны установить self.finished = true.
  • Кроме того, я создал наблюдателя свойств «didSet» для свойств isExecuting и isFinished, где я вызываю willChangeValueForKey и hasChangeValueForKey. Я не 100% уверен, как повторить поведение didSet в Obj C. (This говорит overrride сеттер)

Пожалуйста, обратитесь к видеоуроков Ray Wenderlich о «параллельности», где Сэм Дейвис объясняет создание NSOperation подкласса для асинхронной работы. Обратите внимание, что это только для абонентов, и это объясняется в Swift. Я считаю, что если вы исправите пункты 1 и 2, вы должны увидеть, что ваши проблемы исправлены.

+0

Спасибо, я постараюсь выполнить ваши инструкции, и, к сожалению, я не являюсь подписчиком Рэя Вендерлиха ( – Melany

+0

). Я бы очень рекомендовал стать одним из них, если можно. У них есть несколько удивительных уроков. Https: // www .raywenderlich.com/video-tutorials – shrutim

+0

ОК, может быть, я начну, если удастся справиться с этой проблемой) – Melany

Смежные вопросы