2013-06-29 36 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作为首发。