1

ここでの問題は実際にはブロッキングにあると感じていますが、それは別のことでもあるのかもしれません。住所をジオコーディングし、座標を配列に入れて後で使用しようとしています。

ブロック内の配列に追加しようとしたオブジェクトの 1 つを呼び出そうとすると、一番下に例外が発生します。この例外は、NSLog がブロック テキスト内に出力される前にも発生します。

これを処理する適切な方法は何ですか?ありがとう。

 - (NSMutableArray *)convertAddressToGeocode:(NSString *)addressString
{
    //return array with lat/lng
    __block NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:0];
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    [geocoder geocodeAddressString:addressString
             completionHandler:^ (NSArray* placemarks, NSError* error) {
                 for (CLPlacemark* aPlacemark in placemarks)
                 {
                     // Process the placemark.
                     if (error){
                         NSLog(@"Geocode failed with error: %@", error);
                         [self displayError:error];
                         return;
                     }
                     else {

                         NSArray const *keys = @[@"coordinate.latitude",
                                                 @"coordinate.longitude",
                                                 @"altitude",
                                                 @"horizontalAccuracy",
                                                 @"verticalAccuracy",
                                                 @"course",
                                                 @"speed",
                                                 @"timestamp"];

                         NSString *keylat = keys[0];
                         NSString *keylng = keys[1];

                         if (aPlacemark.location == nil)
                         {
                             NSLog(@"location is nil.");

                         }
                         else if ([keylat isEqualToString:@"coordinate.latitude"] && [keylng isEqualToString:@"coordinate.longitude"])
                         {
                             NSString *lat = @"";
                             NSString *lng = @"";
                             lat = [self displayStringForDouble: [aPlacemark.location coordinate].latitude];
                             lng = [self displayStringForDouble: [aPlacemark.location coordinate].longitude];

                             NSLog(@"This never gets executed"): //THIS NEVER GETS EXECUTED
                             [coordinates addObject:[NSString stringWithFormat:@"%@",lat]];
                             [coordinates addObject:[NSString stringWithFormat:@"%@",lng]];
                         }}}}];
NSLog(@"Array: %@", coordinates[0]);  //EXCEPTION RAISED HERE, Nothing ever gets added
return coordinates;
}

このメソッドがプラグインされるはずのコードは次のとおりですが、convertAddresstoGeocode から座標を取得して convertCoordinatestoRepModel に渡しません。

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    NSString *addressToSearch = self.addressSearchField.text;
    NSMutableArray *coordinateArray = [self convertAddressToGeocode:addressToSearch];
    NSMutableArray *repModelArray = [self convertCoordinatesToRepModel:coordinateArray];
...
}
4

2 に答える 2

1

geocodeAddressStringブロックが実行されるよりも非同期操作である場合

NSLog(@"Array: %@", coordinates[0]);

また、メソッドの呼び出しが終了した後(イベントがすでに処理されている場合)、座標配列が解放され(__block修飾子が原因です-ブロックは__block修飾子でオブジェクトを保持しません)、ブロックで割り当て解除されたcoordinates配列を使用しようとします。

もう一度:

あなたのブロックは後に呼び出されますNSLog(@"Array: %@", coordinates[0]);

フェ:

  1. 削除NSLog(@"Array: %@", coordinates[0]);- その時点で配列が空であることは正常です。
  2. 配列coordinatesをいくつか@propertyに保存し、ブロックで使用した後に解放できます

アップデート:

.h ファイル内

typedef void (^ConverteArrayCallback)(NSArray *coordinates); 

@intrerface

- (void)convertAddressToGeocode:(NSString *)addressString callback:(ConverteArrayCallback) callback;

.m ファイルで

- (void)convertAddressToGeocode:(NSString *)addressString callback:(ConverteArrayCallback) callback { 
    NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:0];
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    [geocoder geocodeAddressString:addressString
             completionHandler:^ (NSArray* placemarks, NSError* error) {
                 for (CLPlacemark* aPlacemark in placemarks)
                 {
                     // Process the placemark.
                     if (error){
                         NSLog(@"Geocode failed with error: %@", error);
                         [self displayError:error];
                         return;
                     }
                     else {

                         NSArray const *keys = @[@"coordinate.latitude",
                                                 @"coordinate.longitude",
                                                 @"altitude",
                                                 @"horizontalAccuracy",
                                                 @"verticalAccuracy",
                                                 @"course",
                                                 @"speed",
                                                 @"timestamp"];

                         NSString *keylat = keys[0];
                         NSString *keylng = keys[1];

                         if (aPlacemark.location == nil)
                         {
                             NSLog(@"location is nil.");

                         }
                         else if ([keylat isEqualToString:@"coordinate.latitude"] && [keylng isEqualToString:@"coordinate.longitude"])
                         {
                             NSString *lat = @"";
                             NSString *lng = @"";
                             lat = [self displayStringForDouble: [aPlacemark.location coordinate].latitude];
                             lng = [self displayStringForDouble: [aPlacemark.location coordinate].longitude];

                                 NSLog(@"This never gets executed"): //THIS NEVER GETS EXECUTED
                                 [coordinates addObject:[NSString stringWithFormat:@"%@",lat]];
                                 [coordinates addObject:[NSString s

tringWithFormat:@"%@",lng]];
                                 }}}

                           if (callback != NULL) {
                                 callback(coordinates);
                           }

      }];
}

それはうまくいくはずです!

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    NSString *addressToSearch = self.addressSearchField.text;
    [self convertAddressToGeocode:addressToSearch callback:^(NSArray *coordinates)
      {  
       self.textView.text = [coordinates objectAtIndex:0];
      }];
}
于 2013-10-10T05:44:04.750 に答える
-1
__block NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:0];

問題はここにあります。上記のコードを次のように置き換えるだけです。

NSMutableArray *coordinates = [[NSMutableArray alloc] init];
于 2013-10-10T05:34:06.833 に答える