iOS:在进程中停止线程/方法

时间:2013-06-29 13:39:03

标签: ios objective-c-blocks grand-central-dispatch nsthread

我有UITextfieldUIButton。例如,用户可以输入搜索“dog”或“cat”之类的单词,它将触发另一个在自定义调度GCD队列上运行的类中的方法来获取图像(大约100个)或者)。

一切正常,除非用户在提取中,决定更改并输入另一个搜索词,如“cat”,然后按下获取按钮,我希望能够停止该线程/方法它从前一个搜索词中获取图像。

我考虑过NSThread(以前从未使用过的东西)或块(一旦方法运行完毕就得到通知),但是块的问题是,一旦方法完成,我会收到通知它的东西,但我需要的是告诉它停止提取(因为用户决定了另一个搜索并输入了另一个搜索词)。

有人可以举一些例子来说明我们如何能够在完成之前在自定义GCD线程上运行时停止循环/方法吗?提前致谢。

2 个答案:

答案 0 :(得分:0)

我建议使用NSOperation,因为它有取消方法,它会取消当前的运行操作。

答案 1 :(得分:0)

我正在使用NSOperationNSOperationQueue在后​​台地图上聚类标记,并在必要时取消操作。 集群标记的功能在NSOperation

的子类中实现

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

您可以使用控制器来管理队列,

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

将操作排入队列,杀死以前的操作等,

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作为首发。