如何在iOS中取消完成处理程序

时间:2015-07-30 08:46:21

标签: ios objective-c completionhandler

我想使用mapkit框架获取附近位置的数组。因此,当用户键入文本字段时,我调用以下函数。

- (void)searchForLocations:(NSString *)string
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(search:) object:nil];
    [self performSelectorInBackground:@selector(search:) withObject:string];
}

- (void)search :(NSString *)string
{
    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
    request.naturalLanguageQuery = string;
    MKCoordinateRegion region;
    MKCoordinateSpan span;
    span.latitudeDelta = 0.05;
    span.longitudeDelta = 0.05;

    region.span = span;
    region.center = newLocation.coordinate;

    request.region = region;

    MKLocalSearch *search = [[MKLocalSearch alloc]initWithRequest:request];

    [search startWithCompletionHandler:^(MKLocalSearchResponse
                                         *response, NSError *error) {
        if (response.mapItems.count == 0)
        {
            NSLog(@"No Matches");
        }
        else
        {

            NSLog(@"name = %@", item.name);
            NSLog(@"Phone = %@", item.phoneNumber);
        }
    }];
}

如您所见,如果有新的输入文本,我想取消之前的搜索。但以前的搜索没有被取消。如何取消之前的搜索?

提前致谢。

3 个答案:

答案 0 :(得分:2)

MKLocalSearch上有cancel method。你试过那个吗?

编辑:啊,对不起,我是个傻瓜。您需要以某种方式保留对旧搜索的引用才能取消它。将它放在一个可以在搜索完成时清除(即设置为nil)的属性中。每当你调用搜索功能时,取消之前的搜索功能(不需要“if”,nil吞下全部),然后创建一个新的

@property (nonatiomic, strong) MKLocalSearch *previousSearch;

- (void)search :(NSString *)string
{
    [self.previousSearch cancel];
    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
    request.naturalLanguageQuery = string;
    MKCoordinateRegion region;
    MKCoordinateSpan span;
    span.latitudeDelta = 0.05;
    span.longitudeDelta = 0.05;

    region.span = span;
    region.center = newLocation.coordinate;

    request.region = region;

    MKLocalSearch *search = [[MKLocalSearch alloc]initWithRequest:request];

    [search startWithCompletionHandler:^(MKLocalSearchResponse
                                     *response, NSError *error) {
        self.previousSearch = nil;
        if (response.mapItems.count == 0)
        {
            NSLog(@"No Matches");
        }
        else
        {

            NSLog(@"name = %@", item.name);
            NSLog(@"Phone = %@", item.phoneNumber);
        }
    }];

    self.previousSearch = search;
}

答案 1 :(得分:0)

MKLocalSearch对象具有cancel方法,您可以使用该方法取消待处理的搜索。您无法在尝试时取消选择器,因为该选择器将在后台调度MKLocalSearch后非常快速地完成。

您需要一个属性来存储您的搜索对象,以便您可以判断它是否仍在搜索并在必要时取消搜索。

@property (strong,nonatomic) MKLocalSearch *localSearch;

- (void)search :(NSString *)string
{
    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
    request.naturalLanguageQuery = string;
    MKCoordinateRegion region;
    MKCoordinateSpan span;
    span.latitudeDelta = 0.05;
    span.longitudeDelta = 0.05;

    region.span = span;
    region.center = newLocation.coordinate;

    request.region = region;

    if (self.localSearch!=nil) {
        if (self.localSearch.searching) {
            [self.localSearch cancel];
            self.localSearch=nil;
        }
    }

    self.localSearch = [[MKLocalSearch alloc]initWithRequest:request];

    [search startWithCompletionHandler:^(MKLocalSearchResponse
                                         *response, NSError *error) {
        if (response.mapItems.count == 0)
        {
            NSLog(@"No Matches");
        }
        else
        {

            NSLog(@"name = %@", item.name);
            NSLog(@"Phone = %@", item.phoneNumber);
        }
    }];
}

答案 2 :(得分:-1)

你可以使用NSBlockOperation。 假设您用于NSBlockOperation的全局变量是blockOperation。然后:

[search startWithCompletionHandler:^(MKLocalSearchResponse
                                     *response, NSError *error) {
    blockOperation = NSBlockOperation(block: { () -> Void in
         if (response.mapItems.count == 0) {
            NSLog(@"No Matches");
         } else {
            NSLog(@"name = %@", item.name);
            NSLog(@"Phone = %@", item.phoneNumber);
         }
    })
}];

然后您可以使用此blockOperation取消您想要的任何位置,如下所示:

blockOperation.cancel()