Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 尝试在完成块内变异数组(CLGeocoder反向地理编码)_Ios_Objective C_Core Location_Reverse Geocoding - Fatal编程技术网

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?这只是任意地向你展示这个概念。使用这个概念和你自己把它应用到你的问题上。我不是来帮你工作的。我不是要你帮我解决问题。我只是想理解你的例子。无论如何,谢谢你