2012-05-02 13 views
3

我有一個NSOperation子類,我想同時運行。爲什麼我的NSOperation子類永不完?

我的理解是,併發操作的工作:

  • 我需要定義isConcurrent返回YES
  • 我需要定義start方法
  • 我需要發送KVOs通知isExecutingisFinished當它這樣做。
  • 使用@synthesize將在isExecutingisFinished的值發生更改時自動發送相應的KVO通知。

儘管如此,我已驗證我的隊列永遠不會移動到下一個項目。

這裏是我的代碼的肉:

@interface MyOperation() 

@property (readwrite) BOOL isExecuting; 
@property (readwrite) BOOL isFinished; 

@end 

@implementation MyOperation 

- (void)start 
{ 
    @autoreleasepool { 
     self.isExecuting = YES; 
     self.HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest]; 

     _HTTPOperation.completionBlock = [^{ 
      [self completed]; 

      self.isExecuting = NO; 
      self.isFinished = YES; 
     } copy]; 

     [_HTTPOperation start]; 
    } 
} 

- (BOOL)isConcurrent 
{ 
    return YES; 
} 

- (void)completed 
{ 
} 

@end 

我缺少什麼?

(這是在iPhone上,但我無法想象的問題。)

回答

4

它看起來像任何志願通知@synthesize將是不夠的NSOperationQueue繼續前進。

手動發送通知解決了這個問題:

- (void)start 
{ 
    @autoreleasepool { 
     [self willChangeValueForKey:@"isExecuting"]; 
     self.isExecuting = YES; 
     [self didChangeValueForKey:@"isExecuting"]; 

     NSURLRequest *URLRequest = [self buildRequest]; 
     if (!URLRequest) { 
      [self willChangeValueForKey:@"isFinished"]; 
      [self willChangeValueForKey:@"isExecuting"]; 
      _isExecuting = NO; 
      _isFinished = YES; 
      [self didChangeValueForKey:@"isExecuting"]; 
      [self didChangeValueForKey:@"isFinished"]; 
      return; 
     } 

     self.HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest]; 

     _HTTPOperation.completionBlock = [^{ 
      [self completed]; 

      [self willChangeValueForKey:@"isFinished"]; 
      [self willChangeValueForKey:@"isExecuting"]; 
      _isExecuting = NO; 
      _isFinished = YES; 
      [self didChangeValueForKey:@"isExecuting"]; 
      [self didChangeValueForKey:@"isFinished"]; 
     } copy]; 

     [_HTTPOperation start]; 
    } 
} 

參見:

1

什麼是你的 「排隊」 是什麼樣子?您是否使用了NSOperationQueue?

無論如何,我會嘗試用我的理解來回答你的問題:P

我想創建一個委託我的NSOperation和具有調用此的志願照顧。

比方說你的NSOperation類看起來像這樣

@interface MyOperation : NSOperation 

@property (assign) id<MyOperationDelegate> delegate; 

你實現

@synthesize delegate; 
@synthesize error; 

    -(id)init{ 
    self = [super init]; 
    if(self){ 
     [self addObserver:self forKeyPath:@"isFinished" 
        options:NSKeyValueObservingOptionNew 
        context:NULL]; 
    } 
    return self; 
} 

-(void)dealloc{ 
    [self removeObserver:self forKeyPath:@"isFinished"]; 
    [super dealloc]; 
} 

-(void)observeValueForKeyPath:(NSString *)keyPath 
        ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 

    if([keyPath isEqualToString:@"isFinished"] == YES){ 
    if([self isCancelled] == NO){ 
     if(delegate != nil && [delegate respondsToSelector:@selector(operationComplete:)]){ 
      [delegate taskComplete:self]; 
     } 
    }else{ 
     if(delegate != nil && [delegate respondsToSelector:@selector(operationCancelled)]){ 
      [delegate taskCancelled]; 
     } 
    } 
} 

}

-(void)main{ 
    [NSException exceptionWithName:kTaskException 
          reason:@"Only to be used with subclass" 
          userInfo:nil]; 
} 

最後你的協議

@class MyOperation; 
@protocol MyOperationDelegate <NSObject> 

@optional 
-(void)operationComplete:(MyOperation*)operation; 
-(void)operationCancelled; 
+0

感謝這個答案,它加入到我所知道有關的NSOperation。我的實際問題是@synthesize沒有發射正確的KVO事件。手動控制事件修復了這個問題。 –

相關問題