JSON 和 iPhone 表格视图

Posted

技术标签:

【中文标题】JSON 和 iPhone 表格视图【英文标题】:JSON and iPhone table view 【发布时间】:2011-06-10 11:43:28 【问题描述】:

我是第一次尝试 JSON 解析器,我需要一些帮助 当我尝试填充表格视图时,它可以正常工作,但是当我滚动表格或选择一行时,应用程序崩溃了。我将不胜感激。

这是我拥有的文件:

#import <UIKit/UIKit.h>
@class RootViewController;
@interface BooksJsonAppDelegate : NSObject <UIApplicationDelegate> 

    UIWindow *window;
    UINavigationController *navigationController;
    NSMutableArray *statuses;
    NSMutableData *responseData;

@property(nonatomic, retain)NSMutableArray *statuses;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

#import "BooksJsonAppDelegate.h"
#import "RootViewController.h"
#import "SBJson.h"


@implementation BooksJsonAppDelegate

@synthesize window;
@synthesize navigationController,statuses;


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions     

    SBJsonParser *parser = [[SBJsonParser alloc] init];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://assignment.golgek.mobi/api/v10/items"]];
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
    statuses = [parser objectWithString:json_string error:nil];


    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];

    return YES;

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
    [responseData setLength:0];


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
    [responseData appendData:data];


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
    NSLog(@"Connection Failed: %@",[error description]);



- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
    [connection release];


- (void)applicationWillResignActive:(UIApplication *)application 



- (void)applicationDidEnterBackground:(UIApplication *)application 


- (void)applicationWillEnterForeground:(UIApplication *)application 



- (void)applicationDidBecomeActive:(UIApplication *)application 



- (void)applicationWillTerminate:(UIApplication *)application 



#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application 



- (void)dealloc 
    [navigationController release];
    [window release];
    [super dealloc];



@end

then the root view controller

#import <UIKit/UIKit.h>
@class DetailView,BooksJsonAppDelegate;
@interface RootViewController : UITableViewController 
    DetailView *detailView;
    BooksJsonAppDelegate *booksAppDelegate;


@end

#import "RootViewController.h"
#import "DetailView.h"
#import "BooksJsonAppDelegate.h"
@implementation RootViewController

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad 
    [super viewDidLoad];
    booksAppDelegate = (BooksJsonAppDelegate *)[[UIApplication sharedApplication] delegate];

 

#pragma mark -
#pragma mark Table view data source

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 1;



// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return [booksAppDelegate.statuses 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] autorelease];
    

    // Configure the cell.
    NSDictionary *aBook = [booksAppDelegate.statuses objectAtIndex:[indexPath row]];

    cell.textLabel.text = [aBook objectForKey:@"title"];
    cell.textLabel.adjustsFontSizeToFitWidth = YES;
    cell.textLabel.font = [UIFont systemFontOfSize:12];
    cell.textLabel.minimumFontSize = 10;
    cell.textLabel.numberOfLines = 4;
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;

    return cell;


#pragma mark -
#pragma mark Table view delegate

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


    NSDictionary *aBook = [booksAppDelegate.statuses objectAtIndex:[indexPath row]];

    detailView = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil];
    // ...
    // Pass the selected object to the new view controller.
    detailView.title = [aBook objectForKey:@"title"];
    [self.navigationController pushViewController:detailView animated:YES];
    [detailView release];




#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning 
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Relinquish ownership any cached data, images, etc that aren't in use.


- (void)viewDidUnload 
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;



- (void)dealloc 
    [super dealloc];



@end

【问题讨论】:

崩溃时控制台出现什么错误? 【参考方案1】:

您可能需要保留您的状态

statuses = [[parser objectWithString:json_string error:nil] retain];

JSON 解析器将返回一个自动释放的对象 :)


正如 Dan 在 cmets 中指出的那样,更好的方法是像这样设置属性:

self.statuses = [parser objectWithString:json_string error:nil];

这样的好处是如果你设置了两次就不会泄露内存,而且你可以使用 KVO 来判断它是否被改变了。好多了:)

【讨论】:

这可能是问题所在——它解释了表是如何加载的,但之后不会做任何事情。等效(但更简单)的事情是在该行中使用 self.statuses 而不是 statuses 并让 @property setter 语义进行保留。 糟糕,我没有意识到这是一个属性;我的错。通过属性设置它会是一种更好的方法。我要更新我的答案! 非常感谢,我只是想知道解析器是否正常。这是我应该编码的方式还是你能给我一些工作要点。问候 您可能会在同步解析时遇到问题 - 应用程序将在启动之前等待服务器响应,并且应用程序在 ios 杀死它们之前只有 20 秒的启动时间!看看后台 URL 加载 - developer.apple.com/library/mac/#documentation/Cocoa/Reference/…【参考方案2】:

您确定booksAppDelegate.statuses 已正确填充吗?

您可以通过在statuses = [parser objectWithString:json_string error:nil]; 之后记录 json 进程来检查这一点 只需添加以下行:NSLog(@"%@",[statuses description]); 以查看将哪些数据放入字典中

【讨论】:

以上是关于JSON 和 iPhone 表格视图的主要内容,如果未能解决你的问题,请参考以下文章

iphone导航控制器和表格视图

如何在同一个 iPhone 视图上拥有表格和其他元素?

在 tableView:cellForRowAtIndexPath 中确定 iPhone 和 iPad 的不同单元格:

iPhone TableView 不填充 JSON 数据

iphone:表格视图有问题

iPhone通过滑出表格视图来滚动UITableview