1

我是这个论坛和 iPhone 开发的新手。由于事实上我知道没有人也做过 iPhone 开发,所以我被困住了,不得不向你们寻求解决方案。

我正在制作一个应用程序从 XMLParser 获取数据,在这些部分中的部分(月)中将数据提供给 UITableView 是行(阶段)。

当我现在运行我的脚本时,它不会这样做。我知道我接近解决方案,但我看不到它。并且没有人来运行我的脚本使得调试变得困难。

我的(演示)XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
  <Stages>
    <Month id="1" name="January">
      <Stage id="1">
        <title>Circumference</title>
        <author>Nicholas Nicastro</author>
        <summary>Eratosthenes and the Ancient Quest to Measure the Globe.</summary>
      </Stage>
      <Stage id="2">
        <title>Copernicus Secret</title>
        <author>Jack Repcheck</author>
        <summary>How the scientific revolution began</summary>
      </Stage>
      <Stage id="3">
        <title>Angels and Demons</title>
        <author>Dan Brown</author>
        <summary>Robert Langdon is summoned to a Swiss research facility to analyze a cryptic symbol seared into the chest of a murdered physicist.</summary>
      </Stage>
    </Month>
    <Month id="2" name="February">
      <Stage id="4">
        <title>Keep the Aspidistra Flying</title>
        <author>George Orwell</author>
        <summary>A poignant and ultimately hopeful look at class and society, Keep the Aspidistra Flying pays tribute to the stubborn virtues of ordinary people who keep the aspidistra flying.</summary>
      </Stage>
    </Month>
  </Stages>

我的 XMLParser 类:

#import <UIKit/UIKit.h>
@class DAFAppDelegate, Stage, Month;

@interface XMLParser : NSObject <NSXMLParserDelegate>
{
  NSMutableString *currentElementValue;
  DAFAppDelegate *appDelegate;

  Stage *aStage;
  Month *aMonth;

}

- (XMLParser *) initXMLParser;

@end


#import "XMLParser.h"
#import "DAFAppDelegate.h"
#import "Stage.h"
#import "Month.h"

@implementation XMLParser

- (XMLParser *) initXMLParser
{
  [super init];
  appDelegate = (DAFAppDelegate *)[[UIApplication sharedApplication] delegate];
  return self;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
  if([elementName isEqualToString:@"Stages"])
  {
      //Initialize the array.
      appDelegate.stages = [[NSMutableArray alloc] init];
  }
  if([elementName isEqualToString:@"Month"])
  {
      //Initialize the Month.
      aMonth = [[Month alloc] init];

      //Extract the attribute here.
      aMonth.name = [attributeDict valueForKey:@"name"];
      aMonth.monthID = [[attributeDict objectForKey:@"id"] integerValue];

      NSLog(@"Reading Month id value :%i", aMonth.monthID);
      NSLog(@"Reading Month name value :%@", aMonth.name);
  }
  if([elementName isEqualToString:@"Stage"])
  {
      //Initialize the Stage.
      aStage = [[Stage alloc] init];

      //Extract the attribute here.
      aStage.stageID = [[attributeDict objectForKey:@"id"] integerValue];

      NSLog(@"Reading id value :%i", aStage.stageID);
  }
  NSLog(@"Processing Element: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{ 
  if(!currentElementValue)
  {
      currentElementValue = [[NSMutableString alloc] initWithString:string];
  }
  else
  {
      [currentElementValue appendString:string];
  }
  NSLog(@"Processing Value: %@", currentElementValue);
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
  if([elementName isEqualToString:@"Stages"])
  return;

  //There is nothing to do if we encounter the Stages element here.
  //If we encounter the Stage element howevere, we want to add the book object to the array
  // and release the object.
  if([elementName isEqualToString:@"Month"])
  {
      [appDelegate.stages addObject:aMonth];
      [aMonth release];
      aMonth = nil;
  }
  if([elementName isEqualToString:@"Stage"])
  {
      [aMonth.monthStage addObject:aStage];
      [aStage release];
      aStage = nil;
  }
  else
  {
      [aStage setValue:currentElementValue forKey:elementName];
      [currentElementValue release];
      currentElementValue = nil;
  }
}

- (void) dealloc
{
  [aStage release];
  [aMonth release];
  [currentElementValue release];
  [super dealloc];
}

@end

我的根视图控制器:

@class DAFAppDelegate;  //Here is my stages mutable array defined

@interface RootViewController : UITableViewController
{
  DAFAppDelegate *appDelegate;
}

@end


#import "RootViewController.h"
#import "DAFAppDelegate.h"
#import "DetailViewController.h"
#import "Stage.h"
#import "Month.h"
#import "AgendaCustomCell.h"

@implementation RootViewController

#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad
{
  [super viewDidLoad];
  appDelegate = (DAFAppDelegate *)[[UIApplication sharedApplication] delegate];
  self.title = NSLocalizedString(@"Agenda", @"Master view navigation title");

  UIImageView *image=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,45,45)] ;
  [image setImage:[UIImage imageNamed:@"topBarIcon.png"]];
  [self.navigationController.navigationBar.topItem setTitleView:image];

  self.tableView.backgroundColor = [UIColor clearColor];
}

#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return [appDelegate.stages count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
  return @"Month Name";
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  return [appDelegate.stages count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"AgendaCustomCell";
  AgendaCustomCell *cell = (AgendaCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil)
  {
      NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:@"AgendaCustomCell" owner:nil options:nil];
      for (id currentObject in topLevelObject)
      {
        if ([currentObject isKindOfClass:[UITableViewCell class]])
        {
          cell = (AgendaCustomCell *)currentObject;
          break;
        }
      }
  }
  UIView *cellBackView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
  cellBackView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"customCellBg.png"]];
  cell.backgroundView = cellBackView;

  Month *aMonth = [appDelegate.stages objectAtIndex:indexPath.section];
  Stage *aStage = [aMonth.monthStage objectAtIndex:indexPath.row];

  cell.titleLabel.text = aStage.title;
  cell.dateLabel.text = aStage.author;
  cell.nameLabel.text = aStage.summary;
  return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}

#pragma mark -
#pragma mark Table view selection

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  //When a row is selected, create the detail view controller and set its detail item to the item associated with the selected row.
 DetailViewController *detailViewController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
 detailViewController.stage = [appDelegate.stages objectAtIndex:indexPath.row];

  // Push the detail view controller.
  [[self navigationController] pushViewController:detailViewController animated:YES];
  [detailViewController release];
}

#pragma mark -
#pragma mark Memory management

- (void)dealloc
{
  [appDelegate release];
  [super dealloc];
}

@end

请帮我解决这个问题。几天来,我一直在为此烦恼,这让我发疯。

提前致谢!!!

4

3 回答 3

1

NSXMLParser 在后台工作,所以我会说当您的 RootViewController tableView 询问您的 appDelegate 时,[appDelegate.stages count];它​​可能尚未准备好或尚未完成解析 XML。

查看实现 'parserDidEndDocument:' 委托回调并在回调后加载 UITableView 数据。

于 2011-03-21T11:15:44.473 回答
0

问题可能与您的tableView:numberOfRowsInSection:实施有关。您让它返回部分的数量,而不是指定部分中的条目数。根据您的测试 XML,这将始终返回 1,这可能是您看到的问题。

要获取部分中的条目数,根据您的示例代码,我会执行以下操作:

Month *aMonth = [appDelegate.stages objectAtIndex:section];
return [aMonth.monthStage count];

这将返回给定月份的条目数。

于 2011-03-21T11:14:12.803 回答
0

Load the xml without the singleton object means in your case appDelegate treat as a singleton.... make the property in the appDelegate of NSXMLParser, and when you intiate the object set to autorelease not in dealloc.

于 2011-03-21T11:19:22.513 回答