无法从Block中将AddObject添加到NSMutableArray [英] Cannot AddObject to NSMutableArray from Block

查看:136
本文介绍了无法从Block中将AddObject添加到NSMutableArray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



当我尝试调用其中一个时,底部会引发异常我试图添加到块中的数组的对象。在块文本中打印出任何NSLog之前,也会引发异常。



处理此问题的正确方法是什么?谢谢。

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

[地址编码器geocodeAddressString:addressString
completionHandler:^(NSArray *地标,NSError *错误){
for(CLPlacemark * aPlacemark in placemarks)
{
//处理地标。
if(error){
NSLog(@Geocode失败,错误:%@,错误);
[self displayError:error];
返回;
}
else {

NSArray const * keys = @ [@coordinate.latitude,
@coordinate.longitude,
@高度,
@horizo​​ntalAccuracy,
@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(@这永远不会执行)://这个从未获得执行
[坐标addObject:[NSString stringWithFormat:@%@,lat]];
[coordinates addObject:[NSString stringWithFormat:@%@,lng]];
}}}}];
NSLog(@Array:%@,坐标[0]); // EXCEPTION RAISED HERE,没有添加任何内容
返回坐标;
}

以下是此方法应插入的代码,但我'我没有得到convertAddresstoGeocode的坐标传递给convertCoordinatestoRepModel:

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


解决方案

如果 geocodeAddressString 是异步操作,则

 之后将执行块操作NSLog(@Array:%@,坐标[0]); 

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



再次:



您的区块将在<$ c $之后被调用c> NSLog(@数组:%@,坐标[0]);



fe:


  1. 删除 NSLog(@数组:%@,坐标[0]); - 在那一刻数组是空的是正常的。

  2. 坐标数组存储在某些中@属性,你可以在块中使用后释放它

更新: < .h文件中的

  typedef void(^ ConverteArrayCallback)(NSArray *坐标); 

@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];

[地址编码器geocodeAddressString:addressString
completionHandler:^(NSArray *地标,NSError *错误){
for(CLPlacemark * aPlacemark in placemarks)
{
//处理地标。
if(error){
NSLog(@Geocode失败,错误:%@,错误);
[self displayError:error];
返回;
}
else {

NSArray const * keys = @ [@coordinate.latitude,
@coordinate.longitude,
@高度,
@horizo​​ntalAccuracy,
@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(@这永远不会执行)://这个从未获得执行
[坐标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];
}];
}


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 array to use later.

An exception is raised down at the bottom when I try to call on one of the objects I tried added to the array in the block. The exception also gets raised before any of the NSLogs ever print out within the block text.

What's the proper way to handle this? Thanks.

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

Here is the code this method is supposed to be plugged into, but I'm not getting the coordinates out of convertAddresstoGeocode to pass to convertCoordinatestoRepModel:

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

解决方案

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

这篇关于无法从Block中将AddObject添加到NSMutableArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆