reverseGeocodeLocation

reverseGeocodeLocation

我正在获取所有图像的GPS信息,并将它们存储在字典中。我会将本字典中的经纬度值传递给reverseGeocodeLocation函数调用,并将结果存储在数据库中。

这里的问题是该函数是一个异步调用,我需要同步整个过程,以便将我的记录插入表中。

例如:我的数组读取以下坐标:32.77003,96.87532。现在,它调用reverseGeocodeLocation函数,将这些坐标作为CLLocation对象传递。现在,在此异步功能返回我返回地理编码的位置名称之前,下一组具有新坐标集的请求将发送到reverseGeocodeLocation函数。这导致将记录插入数据库不一致。

有什么办法可以使整个任务同步?
即让我的for循环等待reverseGeocodeLocation返回一个值,然后继续进行下一个要进行地理编码的记录?

我的一些代码在这里:

for (int imgIdx=0; imgIdx<[imageMetaMutArray count]; imgIdx++)
{
    NSDictionary *localGpsDict = [[NSDictionary alloc]initWithDictionary: [imageMetaMutArray objectAtIndex:imgIdx]];
    imgLatLoc=[localGpsDict valueForKey:@"Latitude"];
    imgLongLoc=[localGpsDict valueForKey:@"Longitude"];
    dateStamp=[localGpsDict valueForKey:@"DateStamp"];
    timeStamp=[localGpsDict valueForKey:@"TimeStamp"];

    if(imgLatLoc && imgLongLoc && dateStamp && timeStamp)
    {
        CLGeocoder *geoCoder=[[CLGeocoder alloc]init];
        CLLocation *currentLocation=[[CLLocation alloc]initWithLatitude:[imgLatLoc doubleValue] longitude:[imgLongLoc doubleValue]];

        [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placeMarks, NSError *err){
        if(err)
        {
            NSLog(@"Reverse geo-coding failed because: %@",err);
            return;
        }


        if(placeMarks && placeMarks.count>0)
        {
            CLPlacemark *placeMarkers=placeMarks[0];
            NSDictionary *locationDictionary=placeMarkers.addressDictionary;

            NSString *country=[locationDictionary objectForKey:(NSString *)kABPersonAddressCountryKey];
            NSString *city=[locationDictionary objectForKey:(NSString *)kABPersonAddressCityKey];
            NSString *state=[locationDictionary objectForKey:(NSString *)kABPersonAddressStateKey];

            NSLog(@"logged in from:");

                if(city)
                {
                    NSLog(@"city: %@",city);
                    locName = [[NSString alloc]initWithString:city];
                    if(state)
                    {
                        NSLog(@"state: %@",state);
                        locName=[locName stringByAppendingString:@","];
                        locName=[locName stringByAppendingString:state];
                    }
                    if(country)
                    {
                        NSLog(@"country: %@",country);
                        locName=[locName stringByAppendingString:@","];
                        locName=[locName stringByAppendingString:country];
                    }
                }
                else
                {
                        if(state)
                        {
                            NSLog(@"state: %@",state);
                            locName = [[NSString alloc]initWithString:state];
                            if(country)
                            {
                                NSLog(@"country: %@",country);
                                locName=[locName stringByAppendingString:@","];
                                locName=[locName stringByAppendingString:country];
                            }
                        }
                        else
                        {
                            NSLog(@"country: %@",country);
                            locName = [[NSString alloc]initWithString:country];
                        }
                    }
                }
                else
                {
                    NSLog(@"Placemark Error code:: %lu\n%@",(unsigned long)placeMarks.count,placeMarks);
                }

                [locName retain];
                NSLog(@"location decoded is: %@",locName);
                /*Call for Insert into Images table*/
               [self insertDataImgTbl:locName];
          });
      }
   }
}

最佳答案

简短的答案是您不能使其同步。

您想要做的是将继续下一个对象的代码移到reverseGeocodeLocation的完成块中,因为这是您可以尽快提交另一个reverseGeocodeLocation请求的代码。让我看看我是否可以在这里做一些伪代码...(也就是说,我还没有编译它,所以可能不完全正确...)

    // in place of the original for loop:
    [self reverseGeocodeForIndex:0];


// Doing the reverse geocode is in a method so you can easily call it from within the completion block.
// Maybe your parameter is not the imgIdx value but is instead some object -- I'm just hacking your posted code
// The point is that your completion block has to be able to tell when
// it is done and how to go on to the next object when it is not done.
(void) reverseGeocodeForIndex:(int) imgIdx {
    NSDictionary *localGpsDict = [[NSDictionary alloc]initWithDictionary: [imageMetaMutArray objectAtIndex:imgIdx]];
    imgLatLoc=[localGpsDict valueForKey:@"Latitude"];
    imgLongLoc=[localGpsDict valueForKey:@"Longitude"];
    dateStamp=[localGpsDict valueForKey:@"DateStamp"];
    timeStamp=[localGpsDict valueForKey:@"TimeStamp"];

    if(imgLatLoc && imgLongLoc && dateStamp && timeStamp)
    {
        CLGeocoder *geoCoder=[[CLGeocoder alloc]init];
        CLLocation *currentLocation=[[CLLocation alloc]initWithLatitude:[imgLatLoc doubleValue] longitude:[imgLongLoc doubleValue]];

        [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placeMarks, NSError *err){
        // completion block
            if(err)
            {
                 // error stuff
            }

            if(placeMarks && placeMarks.count>0)
            {
                 // what happens when you get some data
            }

            // now see if we are done and if not do the next object
            if (imgIdx<[imageMetaMutArray count])
            {
                [self reverseGeocodeForIndex:imgIdx+1];
            } else {
                // Everything is done maybe you want to start something else
            }
        }];
    } else {
        // Since you might not reverseGeocode an object you need an else case
        // here to move on to the next object.
        // Maybe you could be more clever and not duplicate this code.
        if (imgIdx<[imageMetaMutArray count])
        {
            [self reverseGeocodeForIndex:imgIdx+1];
        } else {
            // Everything is done maybe you want to start something else
        }
    }
}

而且,当然,您不能依靠此操作来做其他任何事情,除非您在对最后一个对象进行反向地理编码后可能会启动一些操作。

这种异步编程可以使您发疯。

10-07 12:22