【问题标题】:Use NSArray object outside from json object在 json 对象之外使用 NSArray 对象
【发布时间】:2015-11-27 14:21:58
【问题描述】:

我是 Objective-C 的新手,只是想知道如何在 JSON 之外使用 NSArray 对象。

例如:

NSURL *url = [NSURL URLWithString:@"http://acumen-locdef.elasticbeanstalk.com/service/countries"];


NSURLRequest *request = [NSURLRequest requestWithURL:url];

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

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response,
                                           NSData *data, NSError *connectionError)
 {
     if (data.length > 0 && connectionError == nil)
     {
         NSMutableArray *greeting = [NSJSONSerialization JSONObjectWithData:data
                                                             options:0
                                                               error:NULL];


         for (NSDictionary *countryList in greeting) {

             [myFinalListArray addObject:countryList[@"name"]];

         }

     }

     NSLog(@"%@",myFinalListArray); //(This one showing all results..)

 }];

 NSLog(@"%@",myFinalListArray); //(This one giving empty result)

我已经定义了 myFinalListArray 并在 for 循环中添加了对象。

如果您在循环内或循环外使用NSLog,它将显示结果。但是如果我在}]; 之后使用它(在代码结束之后), 它给了我一个空数组。

【问题讨论】:

  • 因为 sendAsynchronousRequest 在单独的线程上运行,并且您可以看到它正在使用块。 myFinalListArray 填充在块内。
  • 里面的代码是异步调用的。因此,当您在异步请求下方调用 NSLog 时,请求可能尚未完成。您必须等到异步调用完成。
  • 非常感谢您的帮助,有什么可能的解决方案吗?其实我真的很想在外面用这个?
  • 您需要了解异步的含义以及它是如何在Objective-C项目中实现的。只有你能做到。
  • 块在第二个执行这就是为什么你得到空值

标签: ios objective-c json


【解决方案1】:

sendAsynchronousRequest 异步运行,这意味着在请求仍在运行时已经执行了下面的代码,因此 NSLog 正在记录空数组。 只有当请求完成时,数组才会被填满,但你的外部 NSLog 已经被执行了。

【讨论】:

    【解决方案2】:

    使用
    __block NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];

    这应该可行。

    快乐编码。

    【讨论】:

      【解决方案3】:
      -(void)sendRequest
      {    
          NSURL *url = [NSURL URLWithString:@"http://acumen-locdef.elasticbeanstalk.com/service/countries"];
          NSURLRequest *request = [NSURLRequest requestWithURL:url];
          NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];
          [NSURLConnection sendAsynchronousRequest:request
                                     queue:[NSOperationQueue mainQueue]
                         completionHandler:^(NSURLResponse *response,
                                             NSData *data, NSError *connectionError) {
           if (data.length > 0 && connectionError == nil)
           {
               NSMutableArray *greeting = [NSJSONSerialization JSONObjectWithData:data
                                                               options:0
                                                                 error:NULL];
      
              if( !myFinalListArray )
              {
                  myFinalListArray=[[NSMutableArray alloc]init];
              }
               for (NSDictionary *countryList in greeting) {
      
                   [myFinalListArray addObject:countryList[@"name"]];
      
               }
      
           }
      
           [self printArray];
      
          }];
      }
      
      //create method that will execute after response
      -(void) printArray
      {
          NSLog(@"%@",myFinalListArray); //(This one showing all results..)
      }
      

      【讨论】:

        【解决方案4】:

        这会奏效。你可以试试这个。

        - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];
        //Pass here the reference the a array. It will return you the array of you county when downloaded complete.
        [self getURLResponse:&myFinalListArray];
        NSLog(@"countryArray:%@",myFinalListArray);
        }
        
        
        -(void)getURLResponse:(NSMutableArray**)countryArray{
        NSURL *url = [NSURL URLWithString:@"http://acumen-locdef.elasticbeanstalk.com/service/countries"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        NSMutableArray *myFinalListArray = [[NSMutableArray alloc] init];
        
        NSURLResponse *response;
        NSError *error = nil;
        NSData *data = [NSURLConnection sendSynchronousRequest:
                        request returningResponse:&response error:&error];
        NSMutableArray *greeting = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        for (NSDictionary *countryList in greeting) {
            [myFinalListArray addObject:countryList[@"name"]];
        }
        *countryArray = [[NSMutableArray alloc]initWithArray:myFinalListArray copyItems:YES];
        }
        

        【讨论】:

          【解决方案5】:

          如果您在 tableview 中访问myFinalListArray,那么您可以在获取数据后重新加载块内的 tableview。

          或者,如果您在其他任务中访问此数组,那么您必须进行通知调用 (have to add observer),然后发布通知,该通知将调用其他方法并在那里访问您的数组并做进一步的事情。

          【讨论】:

            【解决方案6】:

            sendAsynchronousRequest 关联的代码块在网络获取完成之前不会执行;这需要一些时间。当网络获取发生时,您的代码会继续执行,从紧跟在sendAsynchronousRequest 之后的行开始,即NSLog(@"%@",myFinalListArray); - 但由于网络操作尚未完成,您会得到一个空数组。

            在块中,您需要包含处理数组、更新用户界面或其他任何内容所需的代码(如果您更新 UI,请确保在主线程上调度操作)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-04-03
              • 2015-11-10
              • 1970-01-01
              • 1970-01-01
              • 2012-04-15
              • 1970-01-01
              • 2011-10-25
              相关资源
              最近更新 更多