2011-02-10 47 views
17

我正在使用NSOperationQueue的addOperationWithBlock。從該區塊內,我該如何檢查是否應取消操作?或者訪問任何NSOperation屬性/方法?如何取消用addOperationWithBlock創建的操作?

[myOperationQueue addOperationWithBlock: ^{ 

    while (/* long running loop */) 
    { 
     // how to determine here if I need to cancel? 
     // for that matter, access any NSOperation properties/methods? 

    } 

}]; 

更好的方法來做到這一點使用NSBlockOperation?

回答

49

更好的解決方案可能是使用NSBlockOperation並將其添加到隊列而不是原始塊。你可以這樣做:

__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ 
    while(![operation isCancelled]){ 
    //Some long operation 
    } 
}]; 

[[self queue] addOperation:operation]; 

,就可以使用塊,而讓你在操作一點點更多的控制......和一些更細微NSOperation以及(如添加完成塊,例如能力)。

+0

這幾乎就是我想要的。但它只適用於該特定的區塊。在我的情況下,我的塊調用另一個功能,另一個塊,在那一點上,我不認爲我有權訪問'操作'了。我認爲我的情況將起作用的唯一方法是如果我分類NSOperation。 – roocell 2012-11-21 15:56:06

2

如果您需要在塊中取消操作,則無法真正檢查該操作。如果它在一個區塊中,它應該被取消,那麼它將被取消。訪問NSOperation屬性是不可能的,因爲該塊本身不是NSOperation實例。

示例代碼:

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSOperationQueue *q = [[NSOperationQueue alloc] init]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:10]; 
     NSLog(@"Block 1"); 
    }]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:3]; 
     NSLog(@"Block 2"); 
    }]; 
    [q cancelAllOperations]; 
    [NSThread sleepForTimeInterval:15]; 

    [pool drain]; 
    return 0; 
} 

如果刪除cancelAllOperations然後調用塊火象你所期望的。

我會建議,如果你需要更細粒度地控制操作的取消狀態和與NSOperationQueue的相互作用,你最好使用NSOperation而不是NSBlockOperation。您可以繼承NSOperation來完成此操作。