无法从Block中将AddObject添加到NSMutableArray

时间:2013-10-10 05:27:54

标签: ios objective-c objective-c-blocks nsexception

我觉得我的问题确实存在阻塞,但也许这也是其他问题。我正在尝试转发地理编码地址并将坐标放入数组中以便以后使用。

当我尝试调用我尝试添加到块中的数组的其中一个对象时,底部会引发异常。在块文本中打印出任何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];
...
}

2 个答案:

答案 0 :(得分:1)

如果geocodeAddressString是异步操作,则

之后将执行阻止
NSLog(@"Array: %@", coordinates[0]);

此外,在调用您的方法结束后(当事件已经处理时)坐标数组 释放(因为__block修饰符 - 块不保留带有__block修饰符的对象),并且在您的块中尝试使用dealloced coordinates数组。

再次:

您的阻止将在NSLog(@"Array: %@", coordinates[0]);

之后调用

<强> f.e:

  1. 删除NSLog(@"Array: %@", coordinates[0]); - 在那一刻数组是空的是正常的。
  2. 将您的coordinates数组存储在某个@property中,您可以在使用块中后将其释放
  3. <强>更新

    <。>文件中的

    typedef void (^ConverteArrayCallback)(NSArray *coordinates); 
    
    <{1>}

    下的

    @intrerface
    <。>文件中的

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

    这应该有效!

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

答案 1 :(得分:-1)

__block NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:0];

问题出在这里;只需用以下代码替换上面的代码:

NSMutableArray *coordinates = [[NSMutableArray alloc] init];