当我从Web服务填充搜索数组数据时,有时会收到NSRangeException。在我的示例中,每次从搜索框中键入数据时,我都会重新加载搜索显示控制器表。然后将搜索条目发送到foursquare搜索api,一旦检索到数据,我就会更新我的搜索数组数据模型。
这是它的工作原理:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self searchVenuesFromFoursquare:searchString];
return YES;
}
在上述方法中,每次用户在搜索框中输入值时都会调用委托。然后重新加载搜索表。与此同时,我对Foursquare的网络服务调用正试图检索与搜索词匹配的场地。
- (void)searchVenuesFromFoursquare:(NSString *)searchTerm
{
void(^completionBlock)(NSArray *obj, NSError *err) =
^(NSArray *obj, NSError *err)
{
dispatch_async(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
self.searchVenues = obj;
[self.searchDisplayController.searchResultsTableView reloadData];
});
};
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
if (self.deviceLocation) {
NSString *latLon = [NSString stringWithFormat:@"%g,%g", self.deviceLocation.coordinate.latitude, self.deviceLocation.coordinate.longitude];
[[MakanKakiStore sharedStore]searchVenues:completionBlock withSearchTerm:searchTerm andDeviceLatLng:latLon];
}
else{
[[MakanKakiStore sharedStore]searchVenues:completionBlock withSearchTerm:searchTerm andDeviceLatLng:nil];
}
}
这部分似乎出现了问题。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
VenueSearchTableViewCell *searchVenueCell = [tableView dequeueReusableCellWithIdentifier:@"VenueSearchTableViewCell" forIndexPath:indexPath];
[searchVenueCell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
NSDictionary *venueDict = [self.searchVenues objectAtIndex:indexPath.row];
searchVenueCell.venueName.text = venueDict[@"name"];
return searchVenueCell;
}
}
当cellForRow尝试从searchVenues数组中检索venueDict时,我认为当模型因Web服务调用而突然改变时,可能会发生范围异常。此问题很难复制,因为它取决于Web服务响应速度和用户输入。
我现在的临时解决方法是添加此支票
if (indexPath.row + 1 <= self.searchVenues.count) {
NSDictionary *venueDict = [self.searchVenues objectAtIndex:indexPath.row];
}
这似乎是目前最好的解决方案,可以防止范围异常问题。但是,我想知道是否有解决这个问题的最佳做法? UISearchDisplayController上的大多数教程似乎都在处理在本地初始化而不是远程Web服务器的数据。
因此,如果在为UISearchDisplayController填充数据时有最佳实践方法,有人可以建议我,我真的很感激。
非常感谢你。
答案 0 :(得分:-1)
看看this answer,它很可能会解决您的所有问题。您基本上会限制对Foursquare Web服务的请求。代码:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
static NSTimer *timer;
[timer invalidate];
timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(searchVenuesFromFoursquare:) userInfo:@{@"searchString": searchString} repeats:NO];
return NO;
}
- (void)searchVenuesFromFoursquare:(NSTimer *)timer
{
NSString *searchString = timer.userInfo[@"searchString"];
...
}
对Web服务或数据存储的请求应尽可能不频繁地进行,同时达到预期目标。