使用ASIHTTPRequest使用NSXMLPaerser解析时的空tableview行

时间:2013-04-05 06:10:26

标签: ios xcode uitableview asihttprequest nsxmlparser

我是一个非常新的iPhone开发,我有一个问题。 经过几个小时的搜索和挖掘代码,我可以理解问题的根源(希望),但不知道如何解决它。 问题是tableView单元格在解析器完成之前加载,因此“[array count]”为nil。 当我手动设置'部分中的行数'时,表格会出现,但仅在几秒钟后上下滚动。

我有2个类,一个用于XMLParser,另一个用于显示tableView。 根据我在打开之前读到的这个问题是我需要重新加载tavleview数据但是因为我有2个不同的类我不知道该怎么做。 任何想法?

感谢davance!

这是我的XMLParser代码:

- (void)parserDidStartDocument:(NSXMLParser *)parser
{ 
    self.titles = [[NSMutableArray alloc]init];
    self.descriptions = [[NSMutableArray alloc]init];
    self.links = [[NSMutableArray alloc]init];
    self.pubDate = [[NSMutableArray alloc]init]; 
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{

}

BOOL isItem = NO;
BOOL isTitle = NO;
BOOL isDesription = NO;
BOOL isImg = NO;
BOOL isPubDate = NO;

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"item"]) {
        isItem = YES;
    }

    if ([elementName isEqualToString:@"title"]) {
        isTitle=YES;
        self.titlesString = [[NSMutableString alloc]init];
    }

    if ([elementName isEqualToString:@"description"]) {
        isDesription = YES;
        self.descriptionString = [[NSMutableString alloc]init];;
        self.data = [NSMutableData data];
    }
    if ([elementName isEqualToString:@"pubDate"]) {
        isPubDate = YES;
        self.pubDateString = [[NSMutableString alloc]init];
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    if(isItem && isTitle){
        [self.titlesString appendString:string];
    }
    if (isItem && isDesription) {
        [self.descriptionString appendString:string];
    }
    if (isItem && isPubDate) {
        [self.pubDateString appendString:string];
    }


}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
    if (self.data)
        [self.data appendData:CDATABlock];

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{



    if ([elementName isEqualToString:@"item"]) {
        isItem = NO;



        [self.titles addObject:self.titlesString];
        [self.descriptions addObject:self.descriptionString];
        [self.pubDate addObject:self.pubDateString];
        NSLog(@"%@,%@,%@,",self.titlesString,self.descriptionString,self.pubDate);

    }

    if ([elementName isEqualToString:@"title"]) {
        isTitle=NO;

    }
    if ([elementName isEqualToString:@"description"]) {
        isDesription = NO;


        if ([self.data length] > 0)
        {
            NSString *htmlSnippet = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
            NSString *imageSrc = [self firstImgUrlString:htmlSnippet];
            [self.links addObject:imageSrc];
        }

        self.data = nil;
    }

    if([elementName isEqualToString:@"pubDate"])
        isPubDate = NO;
}

- (NSString *)firstImgUrlString:(NSString *)string
{
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];

    NSTextCheckingResult *result = [regex firstMatchInString:string
                                                     options:0
                                                       range:NSMakeRange(0, [string length])];

    if (result)
        return [string substringWithRange:[result rangeAtIndex:2]];

    return nil;

}

这是我的show tableView代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

       self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"menuButton.png"] style:UIBarButtonItemStyleBordered target:self.viewDeckController action:@selector(toggleLeftView)];

    NSURL *url;

    if (!self.isGetLink)
        url = [NSURL URLWithString:@"http://www.ynet.co.il/Integration/StoryRss2.xml"];
    else
        url = [NSURL URLWithString:self.linkForParsingString];


    if (!self.xmlParser) {
        self.xmlParser = [[XMLparser alloc]init];

        [self.xmlParser LoadXMLWithURl:url];
    }

    self.isGetLink = NO;
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
{

}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.xmlParser.titles count];
}

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


    static NSString *CellIdentifier = @"CustomCell";
    CustomCell *cell = (CustomCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    }

    cell.lblTitle.text = [self.xmlParser.titles objectAtIndex:indexPath.row];
    cell.lblTitle.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.xmlParser.links objectAtIndex:indexPath.row]]];
    cell.imgView.image = [UIImage imageWithData:data];


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


#pragma mark - Table view delegate
NSString *curnentDes;
NSString *currentTitle;
NSString *currentPubDate;

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

    ReadViewController *rvc = [[ReadViewController alloc]initWithNibName:@"ReadViewController" bundle:nil];
    curnentDes = [self.xmlParser.descriptions objectAtIndex:indexPath.row];
    currentTitle = [self.xmlParser.titles objectAtIndex:indexPath.row];

    currentPubDate = [self.xmlParser.pubDate objectAtIndex:indexPath.row];
    NSDateFormatter *inputFormatter = [[NSDateFormatter alloc]init];

    [inputFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss Z"];
    NSDate *inputDate = [inputFormatter dateFromString:currentPubDate];
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc]init];
    [outputFormatter setDateFormat:@"dd/MM/yyyy HH:mm"];
    NSString *outputDate = [outputFormatter stringFromDate:inputDate];

    rvc.description = curnentDes;
    rvc.stitle = currentTitle;
    rvc.pubDate = outputDate;


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

}

2 个答案:

答案 0 :(得分:1)

在解析完成后重新加载表非常简单,你很高兴。滚动后数据出现的原因是您的数组稍后更新,然后调用cellForRowAtIndex并且数组具有内容,因此您可以看到行。

注意:每行都会调用cellForRow(希望你知道)。

使用通知:

在你的解析器类

- (void)parserDidEndDocument:(NSXMLParser *)parser
{ 
  [[NSNotificationCenter defaultCenter ]postNotificationName:@"parsingComplete" object:nil];
}

在您的表视图类的ViewDidLoad中添加此代码并在您的类中的任何位置添加其他函数:

你的viewDidLoad(已编辑)

- (void)viewDidLoad
{
[super viewDidLoad];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(parsingComplete) name:@"parsingComplete" object:nil];
 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"menuButton.png"] style:UIBarButtonItemStyleBordered target:self.viewDeckController action:@selector(toggleLeftView)];

NSURL *url;

if (!self.isGetLink)
    url = [NSURL URLWithString:@"http://www.ynet.co.il/Integration/StoryRss2.xml"];
else
    url = [NSURL URLWithString:self.linkForParsingString];


if (!self.xmlParser) {
    self.xmlParser = [[XMLparser alloc]init];

    [self.xmlParser LoadXMLWithURl:url];
}

self.isGetLink = NO;
}

//处理通知的函数:

-(void)parsingComplete
 {
  NSLog(@"parsing results: %@",self.xmlParser.titles); 

  //change your tableViewName

  [yourTableView reloadData];
 }

//删除通知:

 -(void)dealloc
 {
 [[NSNotificationCenter defaultCenter] removeObserver:self];
 }

答案 1 :(得分:0)

解析完成后重新加载表。使用委托方法从didEndElement方法重新加载表视图。尝试一些这样的想法。

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

     // Reload your table View using delegates 

    }
}