UITableView 中的第二个视图不会显示来自 JSON 的解析数据

Posted

技术标签:

【中文标题】UITableView 中的第二个视图不会显示来自 JSON 的解析数据【英文标题】:Second view in UITableView will not display parsed data from JSON 【发布时间】:2013-01-05 11:28:20 【问题描述】:

我有一个来自 JSON 文件的解析数据。它在我的 UITableView 的第一个视图中就像一个魅力。但是,当我点击一个项目时,它会显示一个空白的第二个视图。

MasterView.h

@interface MasterViewController : UITableViewController

    NSArray *json;


@property (nonatomic, retain) NSArray *json;

@end

MasterView.m

#import "MasterViewController.h"
#import "InformationViewController.h"

@interface MasterViewController ()

@end

@implementation MasterViewController

@synthesize json;

- (void)viewDidLoad

    [super viewDidLoad];

    NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://j4hm.t15.org/ios/console.php"]];
    [self performSelectorOnMainThread: @selector(fetchedData:) withObject: jsonData waitUntilDone: YES];


- (void)fetchedData:(NSData *)responseData

    NSError *error;

    self.json = [NSJSONSerialization JSONObjectWithData: responseData options: kNilOptions error: &error];

    NSLog(@"String is %@", self.json);


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return [json count];


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    

    cell.textLabel.text = [[json objectAtIndex: indexPath.row] objectForKey: @"Console"];

    [cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];

    return cell;



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    InformationViewController *informationViewController = [[InformationViewController alloc] initWithStyle:UITableViewStylePlain];

    informationViewController.title  = [[json objectAtIndex: indexPath.row] objectForKey: @"Console"];
    informationViewController.Information = [[json objectAtIndex: indexPath.row] objectForKey: @"Model"];

    NSLog(@"String is %@", informationViewController.Information);

    [self.navigationController pushViewController: informationViewController animated:YES];


InformationView.h

@interface InformationViewController : UITableViewController

@property (nonatomic, strong) NSArray * Information;

@end

信息视图.m

@interface InformationViewController ()

@end

@implementation InformationViewController

@synthesize Information;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    

    // Configure the cell...

    cell.textLabel.text = [[Information objectAtIndex: indexPath.row] objectForKey: @"Model"];

    [cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];

    return cell;

【问题讨论】:

第一个 NSLog(@"%@",self.Information);告诉我它打印了什么? 我在didSelectRowAtIndexPath 中有NSLog(@"String is %@", informationViewController.Information);,结果是我的MasterView.m 中的2013-01-06 01:03:19.641 JSON04[10867:c07] String is (null)。除此之外,我在viewDidLoad 中也有NSLog(@"viewDidLoad: %@", self.Information);,结果是我的 InformationView.m 中的2013-01-06 01:03:19.642 JSON04[10867:c07] viewDidLoad: (null) 在这里下载项目:cogzentappz.com/demo/iostutorial/TestJson.zip 【参考方案1】:

我在这里发布了另一个答案,只是因为我不想引起混乱。

The Project Code : http://www.cogzentappz.com/demo/iostutorial/TestJson.zip

不要传递选定的值,而是传递整个 ArrayNSUsedDefaults 并使用以下代码检索它们。

  - (void)fetchedData:(NSData *)responseData
    
        NSError *error;

        self.json = [NSJSONSerialization JSONObjectWithData: responseData options: kNilOptions error: &error];

        NSLog(@"String is %@", self.json);

     NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
        NSMutableArray *arrayObj = [[NSMutableArray alloc] init];


        for(int i = 0 ; i<[self.json count] ; i++) 
            [arrayObj addObject:[json objectAtIndex:i]]];
        

        [standardDefaults setObject:arrayObj forKey:@"longArray"];
        [arrayObj release];


    

在下一个视图中,您可以使用以下方法检索数据。 在ViewDidLoadinformationViewcontroller 中使用这个

//reading

NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayObj = [standardDefaults objectForKey:@"longArray"];


for(int i = 0 ; i<[arrayObj count] ; i++) 
        NSLog(@"String is %@",[arrayObj objectAtIndex:i]);
    

根据您的链接,Json 输出如下所示:

NSArray-->NSDictionary-->NSArray-->NSDictionary-->NSArray-->NSDictionary

转到链接:http://json.bloople.net 并发布您的所有 json 输出并按回车键。

因此您必须根据该格式获取值。

for(int i = 0 ; i<[self.json count] ; i++) 
 NSArray *info_Array=[[self.json objectAtIndex:i ]valueForKey:@"Information"];
    NSLog(@"info_Array is %@", info_Array);

    for(int j = 0 ; j<[info_Array count] ; j++)
    

        NSLog(@"Model is %@", [[info_Array objectAtIndex:j ]valueForKey:@"Model"]);
        NSArray *title_Array=[[info_Array objectAtIndex:j ]valueForKey:@"Title"];
        for(int k = 0 ; k<[title_Array count] ; k++)
        
            NSLog(@"Game is %@", [[title_Array objectAtIndex:k ]valueForKey:@"Game"]);
            NSLog(@"Publisher is %@", [[title_Array objectAtIndex:k ]valueForKey:@"Publisher"]);
        

    

    NSString *Console_string= [[dataArray objectAtIndex:i ]valueForKey:@"Console"];
    NSLog(@"String is %@", Console_string);



NSString *Console_string= [[self.Json objectAtIndex:i ]valueForKey:@"Console"];
NSLog(@"String is %@", Console_string);

【讨论】:

谢谢!我现在就试一试。 代码是什么,如果我可以问的话。它有一个例外:2013-01-06 18:37:32.927 JSON04[14725:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (3) beyond bounds (3)' *** First throw call stack: 已经有了改进。您在我的 InformationView.m 的 viewDidLoad 中添加的 NSLog(@"String is %@",[arrayObj objectAtIndex:i]); 显示三个不同的输出。首先是 PlayStation,2013-01-06 19:06:28.335 JSON04[14944:c07] String is Console = PlayStation; Information = (...); 。其次是 Wii,2013-01-06 19:06:28.336 JSON04[14944:c07] String is Console = Wii; Information = (...); 。最后是 Xbox,2013-01-06 19:06:28.336 JSON04[14944:c07] String is Console = Xbox; Information = (...); 但是如果我要在第 3、第 4 或最多第 5 个视图中传递数据,是否需要在 viewDidLoad 中添加代码并重复整个过程? UITableView 长这样,MasterView(显示什么游戏机:PlayStation、Xbox、Wii)。信息视图(显示哪些型号:PS3、PS2、PSX、Wii、Xbox、Xbox 360)。我仍然需要添加 GameView(显示适用于该模型的游戏以及发布者) 顺便说一下,您添加的最后一个代码。我会将其添加到我的 InformationView 的 viewDidLoad 中吗?【参考方案2】:

我认为您必须在获取数据后重新加载数据。现在,您指定NSArrray *json 为空,因为计数返回0。因此,您禁止填充表格视图。获取数据后致电[tableView reloadData];

【讨论】:

fetchData 中的 NSLog 是否打印任何内容? 是的。它打印链接内的数据。 你确定你得到的是 NSArray 而不是字典? 很确定,因为我刚刚从一个旧项目中导入了这些数据,以使我们使用 NSJSONSerialization。在我之前的项目中,我使用的是 NSArray,而不是 NSDictionary。每当我将 json 的类型更改为 NSDictionary 时,都会出现异常。【参考方案3】:

用这个改变你的 MaterView.m 代码

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

InformationViewController *informationViewController = [[InformationViewController alloc] initWithStyle:UITableViewStylePlain];
informationViewController.title  = [[json objectAtIndex: indexPath.row] objectForKey: @"Console"];
informationViewController.Information = [[json objectAtIndex: indexPath.row] objectForKey: @"Model"];
NSLog(@"String is %@", informationViewController.Information);
[self.navigationController pushViewController: informationViewController animated:YES];

希望对你有帮助...

【讨论】:

你确定推送后会带来数据吗? 另外他还需要重新加载UITableView 这是错误的......当UIViewController一旦被推送它就不会回来获取它的数据。您必须在推送之前分配数据。 现在你的回答和@Jahm 在做什么有什么区别? 输出与@Siba 的答案相同。 2013-01-06 01:12:11.754 JSON04[10943:c07] String is (null)

以上是关于UITableView 中的第二个视图不会显示来自 JSON 的解析数据的主要内容,如果未能解决你的问题,请参考以下文章

使用两个视图控制器,第二个不会显示视图

Core Data 应用程序中的 UITableView 不会更新第二个设备的主视图,除非重新启动应用程序,并使用 iCloud 同步

分层 UITableview

WPF 数据绑定到第二个视图

为啥我的第二个视图在转换后没有加载?

使用嵌套在 NSDictionary plist 中的数组中的第二个元素 [1] 的字符串填充 tableview