在 Objective-C 中解析 JSON 后的随机结果

Posted

技术标签:

【中文标题】在 Objective-C 中解析 JSON 后的随机结果【英文标题】:Random results after parsing JSON in Objective-C 【发布时间】:2013-01-30 17:15:55 【问题描述】:

我需要从远程服务器上的多个源解析多个 JSON 对象,并且需要使用单个解析的每个值填充 UITableView:

单个 JSON 源,例如 h**p://WWW.REMOTESERVERWITHJSONSOURCE.NET/A1:


  "id": 0001,
  "main": 
    "mainA": 100,
  ,

单个 JSON 源,例如 h**p://WWW.REMOTESERVERWITHJSONSOURCE.NET/A2:


  "id": 0002,
  "main": 
    "mainA": 200,
  ,

单个 JSON 源,例如 h**p://WWW.REMOTESERVERWITHJSONSOURCE.NET/A3:


  "id": 0003,
  "main": 
    "mainA": 300,
  ,

这里我分配并初始化包含单个 URL 的数组:

    - (void)viewDidLoad 

        // other stuff

        arrayA = [[NSMutableArray alloc] initWithObjects:@"A1", @"A2", @"A3", nil]; //each object A1, A2...An is the single subdirectory of URL for JSON source I need to parse
    

解析方法:

- (void)LoadParse  // this method is called by a UIButton

        main = [[NSMutableArray alloc] init];

        for (int i=0; i < [arrayA count]; i++) 

            NSURL *url = [NSURL URLWithString:
                          [NSString stringWithFormat:
                           @"http://WWW.REMOTESERVERWITHJSONSOURCE.NET/%@",[arrayA objectAtIndex:i]]];

            NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:5.0];

            AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 

            NSMutableDictionary *arrayMain = [JSON valueForKey:@"main"];
            [mainA addObject:[arrayMain objectForKey:@"mainA"]];

            NSLog(@"%@",mainA);

            [table reloadData]; // mainA objects populates rows of UITableView
            [table scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

            

            failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)

            ];

            [operation start];

            
    

NSLog(@"%@",mainA) 的结果;

1st parsing -> NSLog result = random (100-200-300 or 100-300-200 or 200-300-100 or 200-100-300 or 300-200-100 or 300-100-200)
2nd parsing -> (after a few seconds) NSLog result = random (100-200-300 or 100-300-200 or 200-300-100 or 200-100-300 or 300-200-100 or 300-100-200)
3rd parsing -> (after other few seconds) NSLog result = random (100-200-300 or 100-300-200 or 200-300-100 or 200-100-300 or 300-200-100 or 300-100-200)
...

错误:正如您所看到的,每次我按下 UIButton 并开始解析时,我都会得到 mainA 对象的不同序列(然后在表行中),例如:在第一次解析之后,什么我期待吗? 100-200-300 .. 而不是,我得到 100-300-200 或 300-200-100 或其他,所以在下一次解析中,每次加载 parseMethod 时,我都会得到 mainA 的随机序列,而我可以保证远程服务器上 A1-A2-A3 的 mainA 对象分别为 100-200-300。那么,你能帮我吗,这里有什么问题?我晕了,谢谢!

【问题讨论】:

【参考方案1】:

每次执行循环时,都会向服务器发出一个异步请求。每个请求都有一个完成块,当结果从网络服务器返回时执行,但由于这些是异步的,你不知道它们将执行的顺序(无论哪个服务器响应首先到达,都会在它的完成块中首先处理) .

要解决此问题,您可以在声明数组时预先填充:

    main = [@[@"A",@"B",@"C"] mutableCopy];

然后在您的循环中,您可以将每个响应分配给它在数组中的相应位置:

        [main replaceObjectAtIndex:i withObject:[arrayMain objectForKey:@"mainA"]];

您应该预先填充数组,因为您不能在大于数组现有长度的索引处添加对象。

edit 我不清楚您的代码中 arrayA(您预先填充)、mainmainA 之间的关系,但我相信您可以获得原则。

【讨论】:

那我该怎么办? for () 循环是错误的?还有其他代码可以每次以精确的顺​​序获得结果吗?谢谢! @Huxley,请参阅我的更新答案。使用数组时,您需要检查它的内容,因为您无法保证每个网络请求的成功结果。 @Huxley,另请参阅我的编辑...我对您对 mainmainAarrayA 的使用感到有些困惑,但我认为您也可以不使用它很麻烦。 谢谢,我已经测试了你的代码......现在的问题是 NSLog 结果是随机的:100,A,200,300,B,C 或 100,200,300,A,B,C 或 100, A,B,200,C,300 或其他每次解析... @Huxley,没必要,你用mutableCopy创建的

以上是关于在 Objective-C 中解析 JSON 后的随机结果的主要内容,如果未能解决你的问题,请参考以下文章

在 IOS(Objective-C)中有效地解析 JSON 到 Realm DB

如何在 Objective-C iOS 中解析 JSON

在 Objective-C 中解析 JSON 的最漂亮方法?

在 Objective-C 中解析 JSON 数组

Json在objective-c中解析nil字段

在Objective-C中解析JSON响应字符串[重复]