首页 > 解决方案 > 您如何正确实现异步搜索结果?

问题描述

我制作了一个名为TableView的 UITableView 的克隆,它具有自己的数据源和委托,它模仿了原始 UITableView,但打算以不同的方式做一些事情。我还使用自己的委托创建了一个GoogleSuggest类,该委托从已知 URL 请求 google 自动完成建议。

GoogleSuggest类有这个方法:

- (void)requestSuggestionsForText:(NSString *)text {

    [NSThread detachNewThreadSelector:@selector(asyncRequestSuggestionsForText:)
                             toTarget:self
                           withObject:text];
}

当被调用时,它会调度这个私有后台线程:

- (void)asyncRequestSuggestionsForText:(NSString *)text;

当它收到结果时,它会调用这个委托方法:

- (void)googleSuggestDidReceiveResult:(GoogleSuggestResult *)result;

在我把它们放在主ViewController中之前,一切都很好,只需要很少的受控实验。

最初,此方法返回“在后台线程上调用 UI API ”错误:

#pragma mark - GoogleSuggestDelegate

- (void)googleSuggestDidReceiveResult:(GoogleSuggestResult *)result {
    
    _googleSuggestions = result.suggestions;

    [_tableView reloadData];
}

然后我用这个替换了最后一行,它起作用了:

dispatch_async(dispatch_get_main_queue(), ^{
    
    [self.tableView reloadData];
});

现在,我收到“ -[__NSCFNumber length]: unrecognized selector sent to instance 0xbbe7252cd9143595 ”错误。

result.suggestions是一个简单的NSMutableArray 带有NSString变量,任何地方都没有 NSNumber。

这有效,我可以看到所有记录的结果:

- (TableViewCell *)tableView:(tableView *)tableView cellAtIndex:(NSUInteger)index {
    
    TableViewCell *cellView = [[TableViewCell alloc] init];
    
    NSString *result = [_googleSuggestions objectAtIndex:index];
            
    NSLog(@"Result: %@", result);
            
    // cellView.titleLabel.text = result;
    
    return cellView;
}

这也有效,我可以看到记录的所有结果:

- (TableViewCell *)tableView:(tableView *)tableView cellAtIndex:(NSUInteger)index {
    
    TableViewCell *cellView = [[TableViewCell alloc] init];
    
    NSString *result = [_googleSuggestions objectAtIndex:index];
            
    NSLog(@"Result: %@", result);
            
    cellView.titleLabel.text = @"example text";
    
    return cellView;
}

当我尝试将结果分配给 titleLabel.text 时,这会失败:

- (TableViewCell *)tableView:(tableView *)tableView cellAtIndex:(NSUInteger)index {
    
    TableViewCell *cellView = [[TableViewCell alloc] init];
    
    NSString *result = [_googleSuggestions objectAtIndex:index];
            
    NSLog(@"Result: %@", result);
            
    cellView.titleLabel.text = result;
    
    return cellView;
}

这是没有意义的,它显然是一个 NSString 变量分配给一个对象,该对象对 NSString 变量没有问题,如上面的工作示例中所示。

您如何正确实现异步搜索结果?

如何从后台线程正确更新 UI 元素?

标签: iosobjective-casynchronous

解决方案


推荐阅读