我从API中提取数据并填写文章标题(来自Article
对象)的UITableView
。据我所知,我有那部分工作。当我在表格视图中触摸某行时,我正努力展示文章的细节。帮助!需要进行代码审查:试图通过API调用显示对象详细信息(解析XML)
我正确地捕获了文章ID,然后向API发出请求以提取其数据,并执行与我在前一步中加载文章UITableView
所做的操作非常相似的事情。这是我为获得文章详细解析:
// ArticleDetailParser.h
#import <Foundation/Foundation.h>
#import "Article.h"
@class Article;
@class ArticleDetailParser;
@protocol ArticleDetailParserDelegate <NSObject>
- (void)parserDidFinish:(ArticleDetailParser *)parser;
- (void)parser:(ArticleDetailParser *)parser didFailWithError:(NSError *)error;
@end
@interface ArticleDetailParser : NSObject <NSXMLParserDelegate> {
id<ArticleDetailParserDelegate> delegate;
NSMutableString *currentCharacters;
Article *currentArticle;
NSMutableArray *articlesCollection;
NSMutableData *xmlData;
NSURLConnection *connectionInProgress;
}
@property (nonatomic, assign) id<ArticleDetailParserDelegate> delegate;
- (void)parseUrl:(NSString *)url;
- (void)beginParsing:(NSURL *)xmlUrl;
- (Article *)detailedArticle;
@end
而这里的实现:
// ArticleDetailParser.m
#import "ArticleDetailParser.h"
@implementation ArticleDetailParser
@synthesize delegate;
#pragma mark -
#pragma mark Parsing methods
- (void)parseUrl:(NSString *)url
{
NSURL *xmlUrl = [NSURL URLWithString:url];
[self beginParsing:xmlUrl];
}
- (void)beginParsing:(NSURL *)xmlUrl
{
[articlesCollection removeAllObjects];
articlesCollection = [[NSMutableArray alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:xmlUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
// clear existing connection if there is one
if (connectionInProgress) {
[connectionInProgress cancel];
[connectionInProgress release];
}
[xmlData release];
xmlData = [[NSMutableData alloc] init];
// asynchronous connection
connectionInProgress = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
- (Article *)detailedArticle
{
return [articlesCollection objectAtIndex:0];
}
#pragma mark -
#pragma mark NSXMLParserDelegate methods
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[xmlData appendData:data];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqual:@"article"]) {
currentArticle = [[Article alloc] init];
return;
}
if ([elementName isEqual:@"id"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"title"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"alphabetical_title"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"body"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"body_html"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"category"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"authors"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqual:@"last_updated"]) {
currentCharacters = [[NSMutableString alloc] init];
return;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[currentCharacters appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqual:@"article"]) {
[articlesCollection addObject:currentArticle];
[currentArticle release], currentArticle = nil;
return;
}
if ([elementName isEqual:@"id"]) {
[currentArticle setArticleID:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"title"]) {
[currentArticle setTitle:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"alphabetical_title"]) {
[currentArticle setAlphabeticalTitle:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"body"]) {
[currentArticle setBody:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"body_html"]) {
[currentArticle setBodyHtml:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"category"]) {
[currentArticle setCategory:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"authors"]) {
[currentArticle setAuthors:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
if ([elementName isEqual:@"last_updated"]) {
[currentArticle setLastModified:currentCharacters];
[currentCharacters release], currentCharacters = nil;
return;
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];
[parser setDelegate:self];
[parser parse];
[parser release];
[delegate parserDidFinish:self];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[currentArticle release];
currentArticle = nil;
[currentCharacters release];
currentCharacters = nil;
[articlesCollection release];
articlesCollection = nil;
[connectionInProgress release];
connectionInProgress = nil;
[xmlData release];
xmlData = nil;
NSLog(@"connection failed: %@", [error localizedDescription]);
[delegate parser:self didFailWithError:error];
}
@end
做任何事情你立场是错误的?这里是我的控制,我正在做使用ArticleDetailParser
的:
// ArticleDetailViewController.h
#import <UIKit/UIKit.h>
#import "ArticleDetailParser.h"
@class Article;
@interface ArticleDetailViewController : UIViewController <ArticleDetailParserDelegate> {
Article *article;
UILabel *aTitle;
UILabel *aCategory;
UILabel *aAuthors;
UIActivityIndicatorView *activityView;
}
@property (nonatomic, assign) Article *article;
@property (nonatomic, assign) UIActivityIndicatorView *activityView;
- (void)loadArticleDetail;
- (void)showArticle;
@end
所述控制器的实现:
// ArticleDetailViewController.m
#import "ArticleDetailViewController.h"
@implementation ArticleDetailViewController
@synthesize article, activityView;
#pragma mark -
#pragma mark init and dealloc
- (id)init
{
[super initWithNibName:nil bundle:nil];
[[self navigationItem] setTitle:@"Article Details"];
article = [[Article alloc] init];
aTitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 280, 25)];
aCategory = [[UILabel alloc] initWithFrame:CGRectMake(20, 30, 280, 25)];
aAuthors = [[UILabel alloc] initWithFrame:CGRectMake(20, 50, 280, 25)];
activityView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[[self activityView] sizeToFit];
[[self activityView] setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin)];
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
return [self init];
}
- (void)dealloc {
[article release];
[aTitle release];
[aCategory release];
[aAuthors release];
[activityView release];
[super dealloc];
}
#pragma mark -
#pragma mark Web Service methods
- (void)loadArticleDetail
{
NSString *urlToRequest = [NSString stringWithFormat:@"http://wvencyclopedia.org/articles/%@.xml", [[self article] articleID]];
ArticleDetailParser *aDetailParser = [[ArticleDetailParser alloc] init];
[aDetailParser setDelegate:self];
[aDetailParser parseUrl:urlToRequest];
[aDetailParser release];
}
#pragma mark -
#pragma mark ArticleDetailParserDelegate methods
- (void)parserDidFinish:(ArticleDetailParser *)parser
{
article = [parser detailedArticle];
[[self activityView] stopAnimating];
}
- (void)parser:(ArticleDetailParser *)parser didFailWithError:(NSError *)error
{
NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:errorString delegate:nil cancelButtonTitle:@"OK" destructiveButtonTitle:nil otherButtonTitles:nil];
[actionSheet showInView:[[self view] window]];
[actionSheet autorelease];
}
#pragma mark -
#pragma mark UIView methods
- (void)showArticle
{
[aTitle setText:[[self article] title]];
[[self view] addSubview:aTitle];
[aTitle release];
[aCategory setText:[[self article] category]];
[[self view] addSubview:aCategory];
[aCategory release];
[aAuthors setText:[[self article] authors]];
[[self view] addSubview:aAuthors];
[aAuthors release];
}
#pragma mark -
#pragma mark UIViewController methods
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self loadArticleDetail];
[[self activityView] startAnimating];
[self showArticle];
}
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)loadView
{
[super loadView];
UIBarButtonItem *loadingView = [[UIBarButtonItem alloc] initWithCustomView:[self activityView]];
[[self navigationItem] setRightBarButtonItem:loadingView];
}
#pragma mark -
#pragma mark Memory Management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
@end
这是书籍教程超出了我的第一真正 iPhone应用程序,并我也是Objective-C的新手,所以我很容易误解内存管理方面的问题,并在视图中获取标签。
发生了什么事情是我点击表格视图加载一篇文章,第一篇文章只显示文章标题。然后我回去,尝试点击另一个,它崩溃。
我很抱歉张贴这么多的代码,但我想如果有人选择帮助它可能是最好的整个图片。
非常感谢你,如果你应该承担这样的任务!
在发布所有代码之前,您应该尝试自己调试一段时间。使用XCode的运行和调试选项,并在应用程序崩溃时使用日志查看堆栈跟踪。您也可以在您的代码中放置NSLog(),以确保您的变量包含您认为应包含的内容。如果您收到任何您无法解读的错误消息,请告诉我们! – Tozar 2010-11-10 05:48:34