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
不要传递选定的值,而是传递整个 Array
到 NSUsedDefaults
并使用以下代码检索它们。
- (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];
在下一个视图中,您可以使用以下方法检索数据。
在ViewDidLoad
的informationViewcontroller
中使用这个
//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 同步