【问题标题】:How to cancel a completion handler in iOS如何在 iOS 中取消完成处理程序
【发布时间】:2015-07-30 08:46:20
【问题描述】:

我想使用 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);
        }
    }];
}

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

提前致谢。

【问题讨论】:

    标签: ios objective-c completionhandler


    【解决方案1】:

    在 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;
    }
    

    【讨论】:

    • 我不明白为什么它会在我的案例中显示以前的搜索结果。
    【解决方案2】:

    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);
            }
        }];
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用 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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-16
        • 1970-01-01
        • 2013-11-24
        • 2012-09-15
        • 1970-01-01
        相关资源
        最近更新 更多