2013-04-05 1 views
1

저는 꽤 새로운 iPhone 개발이고 문제가 있습니다. 몇 시간 동안 검색하고 코드를 파헤 쳐서 문제의 근원을 이해할 수 있었지만 해결 방법을 모릅니다. 문제는 파서가 완료되기 전에 tableView 셀이로드되므로 "[배열 수]"가 nil입니다. '섹션의 행 수'를 수동으로 설정하면 표가 나타나지만 몇 초 후에 위아래로 스크롤합니다.ASIHTTPRequest를 사용하여 NSXMLPaerser로 구문 분석 할 때 빈 테이블 뷰 행

나는 XMLParser와 tableView를 보여주기위한 두 개의 클래스를 가지고있다. 내가 전에이 질문을 열어 읽는 것에 따르면 내가 tavleview 데이터를 다시로드해야하지만 내가 어떻게 해야할지 모르겠다 2 다양한 수업을 가지고 있기 때문에. 아이디어가 있습니까?

감사합니다. 여기

내 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; 

} 

여기 내 쇼를 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]; 

} 

답변

1

매우 간단 다시로드, 당신은에 좋은 가기. 스크롤 한 후에 데이터가 나오는 이유는 나중에 배열이 업데이트되고 cellForRowAtIndex가 호출되고 배열에 내용이 있으므로 행이 표시됩니다.

참고 : cellForRow가 모든 행에 대해 호출됩니다 (알고 계 셨음).

사용 알림 : (

당신의 viewDidLoad 편집 :

테이블 뷰 클래스의 viewDidLoad에서
- (void)parserDidEndDocument:(NSXMLParser *)parser 
{ 
    [[NSNotificationCenter defaultCenter ]postNotificationName:@"parsingComplete" object:nil]; 
} 

이 코드를 추가하고 UR 수업 시간에 어디 다른 기능을 추가하여 파서 클래스에서

)

- (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)dealloc 
{ 
[[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 
+0

빠른 응답 주셔서 감사합니다. 하지만 어떻게 데이터를 다시로드해야합니까? 내 in - (void) parserDidEndDocument : (NSXMLParser *) 파서? 그렇다면 어떻게 될까요? 내가 말했듯이 2 가지 다양한 클래스가 있습니다 .. xmlparser 클래스에서 테이블 뷰를 다시로드 할 수 없습니다. – OshriALM

+0

위임 또는 알림을 사용할 수 있습니다. 어느 것을 시도하고 싶은가요?. – satheeshwaran

+0

먼저 통보를하겠습니다. – satheeshwaran

0

새로 고침 :

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

    //change your tableViewName 

    [yourTableView reloadData]; 
} 

// 통지를 제거. 대리자 메서드를 사용하여 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 

    } 
} 
+0

을 디버깅하려면 malloc_error_break에 중단 점을 설정하십시오. – OshriALM

+0

대리자는 특정 작업을 수행하기 위해 위임 발사 엔터티와받는 엔터티의 작업을 통신하거나 위임하는 데 사용됩니다. NSNotification은 매우 단순하지만 여러 사람이 알림을 받으면 하나의 수신자 만있는 경우 위임은 더 좋은 방법입니다. – satheeshwaran

+0

@OshriALM satheeshwaran 대답에 대한 질문이 수정되었습니다. NSNotification을 델리게이트보다 이해하기 쉽도록 해보십시오. – Ganapathy