Ios 尝试在完成块内变异数组(CLGeocoder反向地理编码)
我在我的核心数据数据库中存储了城市名称和坐标,并试图获取州信息。 为了做到这一点,我像这样反向地理编码Ios 尝试在完成块内变异数组(CLGeocoder反向地理编码),ios,objective-c,core-location,reverse-geocoding,Ios,Objective C,Core Location,Reverse Geocoding,我在我的核心数据数据库中存储了城市名称和坐标,并试图获取州信息。 为了做到这一点,我像这样反向地理编码 code moved below 问题是locationStr对象未存储在tempcity数组中。我已经在块内部进行了测试,我知道locationStr正在创建并存在 我已经想了好几个小时了。有人能帮我澄清一下吗 如果你需要任何其他信息,请告诉我 编辑: 该数组用于填充表视图。代码位于一个helper方法中,该方法返回一个数组(即tempcityarray)。在for循环之后,我将根据ni
code moved below
问题是locationStr
对象未存储在tempcity
数组中。我已经在块内部进行了测试,我知道locationStr
正在创建并存在
我已经想了好几个小时了。有人能帮我澄清一下吗
如果你需要任何其他信息,请告诉我
编辑:
该数组用于填充表视图。代码位于一个helper方法中,该方法返回一个数组(即tempcity
array)。在for循环之后,我将根据nil和0检查数组
下面是视图控制器中的UISearchControllerDelegate
方法的外观
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchText = searchController.searchBar.text;
if ([searchText length] >= 3)
{
self.resultsArray = [[[CityHelper sharedInstance]testWithSearch:searchText]mutableCopy];
[self.resultsTableView reloadData];
}
}
在CityHelper
课程中
- (NSArray *) testWithSearch: (NSString *)search
{
NSArray *cities = [self getCitiesStartingWith:search];//stores NSManagedObject subclass instances with cityName, lat, and long.
NSArray *coords = [self coordinatesForCities:cities];
NSMutableArray *tempCities = [NSMutableArray new];
for (MMCoordinate *coordinate in coords) {
CLGeocoder *geocoder = [CLGeocoder new];
CLLocation *location = [[CLLocation alloc]initWithLatitude:[coordinate.latitude floatValue]
longitude:[coordinate.longitude floatValue]];
if (![geocoder isGeocoding]) {
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = placemarks[0];
NSString *locationStr = [NSString stringWithFormat:@"%@, %@", placemark.locality, placemark.administrativeArea];
[tempCities addObject:locationStr];
}];
}
}
if (!tempCities) {
NSLog(@"its nil");
}
if ([tempCities count] == 0) {
NSLog(@"its 0");
}
return tempCities;
}
这总是返回一个空(0计数)数组根本原因是将
临时性
声明为\u块
变量。由于\u块
,iOS在进入完成块时不会保留临时性
。由于完成块稍后执行,并且tempcity
是一个局部变量,因此它实际上在完成块开始执行时被释放
请按如下方式声明临时城市
:
NSMutableArray *tempCities = [NSMutableArray new];
基本上,您的情况可以通过一个简单的代码片段来说明:
- (void)someMethod
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// this will be executed in two seconds
NSLog(@"I'm the last!");
});
NSLog(@"I'm first!");
}
传递给dispatch_after的块在方法调用结束后被调用,就像传递给reverseGeocodeLocation:completionHandler:
的块一样。您将在控制台上看到我是第一个第一个,然后我是最后一个代码>
你该怎么办?
您需要通过向您的方法引入回调来解决这个问题,因为您的方法在后台执行操作,并且在完成时需要回调。当您想知道如何声明块(例如在方法中)时,本网站将介绍如何使用块语法:
在您的情况下,还需要在reversegeocodocation:completionHandler
块中确定何时调用回调,您应该将其作为参数添加到testWithSearch
。例如,您可以在每次调用reverseGeocodeLocation:completionHandler
时增加计数器,并在每次调用completionHandler时减少计数器。当计数器达到0时,使用数组结果调用testWithSearch
回调
例如:
- (void)doSomething:(dispatch_block_t)callback
{
// we need __block here because we need to
// modify that variable inside a block
// try to remove __block and you'll see a compiler error
__block int counter = 0;
for (int i = 0; i < 15; i ++) {
counter += 1;
dispatch_async(dispatch_get_main_queue(), ^{
counter -= 1;
if (counter <= 0 && callback) {
callback();
}
});
}
}
-(void)doSomething:(调度块)回调
{
//我们需要封锁这里,因为我们需要
//在块内修改该变量
//尝试删除_块,您将看到编译器错误
__块int计数器=0;
对于(int i=0;i<15;i++){
计数器+=1;
dispatch\u async(dispatch\u get\u main\u queue()^{
计数器-=1;
如果(请记住,您处理的是异步代码。实际上,reverseGeocodeLocation是异步调用的,但在主线程上调用完成块。线程与您的问题无关。值在for循环完成后很长时间才添加到数组中,无论这是什么方法,都早就返回了。哦。我不知道。你是否至少为临时性增加了一个值?
?谢谢,但即使这样做,临时性也不是零,但仍然没有对象。我认为答案更接近@rmaddy所说的。实际上我也是这么说的。你在哪里检查临时性
”项目的计数?在完成块内,即立即在[tempcity addObject:locationStr];
行之后添加日志记录,如NSLog(@“count=%d”,tempcity.count)
在这一行之后?这个答案有误导性。问题只是在方法返回后很久才调用完成块。简单地删除\uu块
限定符将不会对这里的结果产生影响。@rmaddy,问题是当问题的作者检查临时性
中的值时。如果在cCompletion block然后我的答案是完全正确的。如果在block之外,那么是的,问题是向该数组添加对象的代码是在检查数组的内容后执行的。回答很好。你能给我举个例子吗?谁在调用doSomething
方法?为什么是15?这只是任意地向你展示这个概念。使用这个概念和你自己把它应用到你的问题上。我不是来帮你工作的。我不是要你帮我解决问题。我只是想理解你的例子。无论如何,谢谢你