2013-06-29 35 views
0

我有一個UITextfield和一個UIButton。例如,用戶可以輸入搜索詞,如「狗」或「貓」,它將觸發另一個類中的方法,該類在自定義調度GCD隊列上獲取圖像(大約100個左右)。iOS:在進程中間停止線程/方法

一切工作正常,除非用戶在抓取中,決定改變並輸入另一個搜索詞,如「貓」,然後按下抓取按鈕,我想能夠停止該線程/方法而它正在從上一個搜索詞中提取圖像。

我曾想過NSThread(我以前從未使用過)或塊(在方法運行完成後會得到通知),但塊的問題是,一旦方法結束後,我會收到通知,但我需要的是告訴它停止提取(因爲用戶已決定進行另一次搜索並輸入另一個搜索詞)。

有人可以舉我一些樣品,至於我們如何能夠在它完成之前在定製GCD線程上運行時停止循環/方法嗎?提前致謝。

回答

0

我會推薦使用NSOperation,因爲它有取消方法,它將取消當前的運行操作。

+1

如果您使用'NSOperation',您需要確保在代碼中檢查isCancelled以檢測何時中止。 – mttrb

0

我使用NSOperationNSOperationQueue在後臺對地圖上的標記進行聚類,並在必要時取消操作。

ClusterMarker.h:

@class ClusterMarker; 

@protocol ClusterMarkerDelegate <NSObject> 

- (void)clusterMarkerDidFinish:(ClusterMarker *)clusterMarker; 

@end 

@interface ClusterMarker : NSOperation 

-(id)initWithMarkers:(NSSet *)markerSet delegate:(id<ClusterMarkerDelegate>)delegate; 
// the "return value" 
@property (nonatomic, strong) NSSet *markerSet; 
// use the delegate pattern to inform someone that the operation has finished 
@property (nonatomic, weak) id<ClusterMarkerDelegate> delegate; 

@end 

和ClusterMarker.m:

@implementation ClusterMarker 

-(id)initWithMarkers:(NSSet *)markerSet delegate:(id<ClusterMarkerDelegate>)delegate 
{ 
    if (self = [super init]) { 
     self.markerSet = markerSet; 
     self.delegate = delegate; 
    } 
    return self;  
} 

- (void)main { 
    @autoreleasepool { 

     if (self.isCancelled) { 
      return; 
     } 

     // perform some Überalgorithmus that fills self.markerSet (the "return value") 

     // inform the delegate that you have finished 
     [(NSObject *)self.delegate performSelectorOnMainThread:@selector(clusterMarkerDidFinish:) withObject:self waitUntilDone:NO]; 
    } 
} 

@end 

您可以使用您的控制器來管理 集羣標記功能是在NSOperation一個子類實現排隊,

self.operationQueue = [[NSOperationQueue alloc] init]; 
self.operationQueue.name = @"Überalgorithmus.TheKillerApp.makemyday.com"; 
// make sure to have only one algorithm running 
self.operationQueue.maxConcurrentOperationCount = 1; 

排隊工作ations,殺了以前的操作等,

ClusterMarker *clusterMarkerOperation = [[ClusterMarker alloc] initWithMarkers:self.xmlMarkerSet delegate:self]; 
// this sets isCancelled in ClusterMarker to true. you might want to check that variable frequently in the algorithm 
[self.operationQueue cancelAllOperations]; 
[self.operationQueue addOperation:clusterMarkerOperation]; 

當操作完成向回調回應:

- (void)clusterMarkerDidFinish:(ClusterMarker *)clusterMarker 
{ 
    self.clusterMarkerSet = clusterMarker.markerSet; 

    GMSProjection *projection = [self.mapView projection]; 
    for (MapMarker *m in self.clusterMarkerSet) { 
     m.coordinate = [projection coordinateForPoint:m.point]; 
    } 

// DebugLog(@"now clear map and refreshData: self.clusterMarkerSet.count=%d", self.clusterMarkerSet.count); 
    [self.mapView clear]; 
    [self refreshDataInGMSMapView:self.mapView]; 
} 

如果我沒有記錯我以前this tutorial on raywenderlich.com作爲首發。