Cannot AddObject to NSMutableArray from Block

后端 未结 2 604
野性不改
野性不改 2021-01-23 17:32

I have a feeling that my problem here is really with blocking, but maybe it\'s something else too. I am trying to forward geocode an address and place the coordinates into an ar

2条回答
  •  囚心锁ツ
    2021-01-23 18:17

    if geocodeAddressString is async operation than your block will be performed after

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

    also, after call of your method ends (when event already handled) the coordinates array released (it is because of __block modifier - blocks do not retain objects with __block modifier), and in your block you try to use dealloced coordinates array.

    Once again:

    Your block will be called after NSLog(@"Array: %@", coordinates[0]);

    f.e.:

    1. Remove NSLog(@"Array: %@", coordinates[0]); - it is normal that in that moment array is empty.
    2. Store your coordinates array in some @property , you can release it after using in block

    UPDATE:

    in .h file

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

    under @intrerface

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

    in .m file

    - (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);
                               }
    
          }];
    }
    

    That should works!

    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        NSString *addressToSearch = self.addressSearchField.text;
        [self convertAddressToGeocode:addressToSearch callback:^(NSArray *coordinates)
          {  
           self.textView.text = [coordinates objectAtIndex:0];
          }];
    }
    

提交回复
热议问题