2011-06-30 55 views
2

我有一個UITableView填充從XML解析的數據。解析工作,但表格保持空白。UITableViewController:Data Parse但是`numberOfRowsInSection:`返回NULL。

控制檯顯示URL的XML表單被解析並顯示其組件。它還顯示了當用不同的函數詢問tableview的行時應該有的對象的數量,但numberOfRowsInSection:返回Null。因此,模擬器中的tableView保持空白。

這是我的代碼。這是一個從教程簡單的代碼:

+++++++++++++++++ RootViewController.h ++++++++++++++++++++++

#import <UIKit/UIKit.h> 

@interface RootViewController : UITableViewController <NSXMLParserDelegate>{ 

    IBOutlet UITableView *newsTable; 
    UIActivityIndicatorView *activityIndicator; 
    CGSize cellSize; 
    NSXMLParser *rssParser; 
    NSMutableArray *stories; 
    NSMutableDictionary *item; 
    NSString *currentElement; 
    NSMutableString *currentTitle, *currentDate, *currentSummary, *currentLink; 
} 

@property (nonatomic, retain) NSMutableArray *stories; 

@property (nonatomic, retain) IBOutlet UITableView *newsTable; 

-(void)parseXMLFileAtURL:(NSString *)URL; 

@end 


+++++++++++++++++++++++++++ RootViewController.m ++++++++++++++++++++++++++++++++++++++ 

#import "RootViewController.h" 


@implementation RootViewController 
@synthesize newsTable, stories; 


-(void)viewDidLoad { 

    [super viewDidLoad]; 

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 

    // self.navigationItem.rightBarButtonItem = self.editButtonItem; 
} 


-(void)viewWillAppear:(BOOL)animated { 

    [super viewWillAppear:animated]; 

    [newsTable reloadData]; 
} 


-(void)viewDidAppear:(BOOL)animated { 

    [super viewDidAppear:animated]; 

    if([stories count] == 0){ 
     NSString *path = @"http://feeds.feedburner.com/TheAppleBlog"; 

     [self parseXMLFileAtURL:path];  
    } 

    cellSize = CGSizeMake([newsTable bounds].size.width, 60); 

} 

// Customize the number of sections in the table view. 

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

    return 1; 
} 


-(void)parseXMLFileAtURL:(NSString *)URL { 

    stories = [[NSMutableArray alloc] init]; 

    NSURL *xmlURL = [NSURL URLWithString:URL]; 

    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL]; 

    [rssParser setDelegate:self]; 

    [rssParser setShouldProcessNamespaces:NO]; 

    [rssParser setShouldReportNamespacePrefixes:NO]; 

     [rssParser setShouldResolveExternalEntities:NO]; 

    [rssParser parse]; 
} 

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

    NSLog(@"Found file and started parsing"); 
} 

-(void) parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ 

    NSString *errorString = [NSString stringWithFormat:@"Unable to download story feed from the website (error code %i)", [parseError code]]; 

    NSLog(@"error parsing XML: %@", errorString); 

    UIAlertView *errorAlert = [[UIAlertView alloc]:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitle:nil]; 

    [errorAlert show]; 
} 

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ 

    NSLog(@"Found this Element %@", elementName); 
    currentElement = [elementName copy]; 


    if ([elementName isEqualToString:@"item"]) { 

     item = [[NSMutableDictionary alloc] init]; 

     currentTitle = [[NSMutableString alloc] init]; 
     currentDate = [[NSMutableString alloc] init]; 
     currentSummary = [[NSMutableString alloc] init]; 
     currentLink = [[NSMutableString alloc] init];    
    } 
} 

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

    NSLog(@"End this Element %@", elementName); 

    if ([elementName isEqualToString:@"item"]) { 

     [item setObject:currentTitle forKey:@"title"]; 
     [item setObject:currentLink forKey:@"link"]; 
     [item setObject:currentSummary forKey:@"summary"]; 
     [item setObject:currentDate forKey:@"date"]; 

     [stories addObject:[item copy]]; 
     NSLog(@"adding Story : %@",currentTitle); 
    } 

} 

// Customize the number of rows in the table view. 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    NSLog(@"Count is = %@", [stories count]); 

    return [stories count]; 
} 


-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 

    NSLog(@"Found characters: %@", string); 

    if([currentElement isEqualToString:@"title"]){ 

     [currentTitle appendString:string]; 
     NSLog(@"The Title is : %@", currentTitle); 
    } 
    else if([currentElement isEqualToString:@"link"]){ 
     [currentLink appendString:string]; 
     NSLog(@"The Link is : %@", currentLink); 
    } 
    else if([currentElement isEqualToString:@"description"]){ 
     [currentSummary appendString:string]; 
     NSLog(@"The summary is : %@", currentSummary); 
    } 
    else if([currentElement isEqualToString:@"pubDate"]){ 
     [currentDate appendString:string]; 
     NSLog(@"The Date is : %@", currentDate); 
    } 

} 

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

    [activityIndicator stopAnimating]; 

    [activityIndicator removeFromSuperview]; 

    NSLog(@"Stories array has %d items", [stories count]); 

    NSLog(@"Stories are : %@",stories); 
} 


// Customize the appearance of table view cells. 

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

    static NSString *MyIdentifier = @"MyIdentifier"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 

    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease]; 
    } 

    // Configure the cell. 

    cell.textLabel.text = (NSString *)[[stories objectAtIndex:indexPath.row] objectForKey:@"title"]; 

    return cell; 
} 

-(void)dealloc { 

    [super dealloc]; 

    [newsTable release]; 
    [currentDate release]; 
    [currentElement release]; 
    [currentSummary release]; 
    [currentLink release]; 
    [stories release]; 
    [item release]; 
    [currentTitle release]; 
    [rssParser release]; 
} 
+0

@ TechZen - 您的編輯已經很好,感謝您花時間在今天和其他幾個帖子上幫助其他人。 –

+0

@Tim Post - 沒有什麼大不了的,我現在躺在牀上,所以我在這個時間殺了我,因爲我無法完成任何真正的工作。 – TechZen

回答

2

你必須告訴表視圖有新通過在之後調用reloadData來解析XML。

+0

我在viewWillAppear()中定義了[newsTable reloadData] definintion –

+0

顧名思義,'viewDidAppear'(你的數據被解析的地方)在'viewWillAppear'之後被調用。'viewWillAppear'中的'reloadData'調用沒有效果,因爲沒有數據。 – omz

+0

+1這是正確的答案。 – TechZen

0

newsTable插座是否正確連接到IB中的表格視圖?而且,該表的dataSource插座是否設置爲您的視圖控制器?

+0

是的,「文件所有者」的newsTable插座連接到IB中的tableView。表的數據源也連接到文件的所有者 –

0

要擴大@omz's correct answer:

方法numberOfRowsInSection沒有返回NULL,但零。 (在Objective-C中,nil ==零且Null是單身對象。)

將返回零的唯一原因是如果[stories count]返回零並且[stories count]將返回零的唯一原因是如果它沒有元素。既然你已經確認瞭解析工作,並且stories有元素,那麼tableview必須在解析發生之前尋找數據。

這種方法被稱爲第一,它是唯一的地方重新加載數據:

-(void)viewWillAppear:(BOOL)animated { 

    [super viewWillAppear:animated]; 

    [newsTable reloadData]; 
    // You trigger the tableview to call numberOfRowsInSection before stories is populated. 
} 

這種方法被稱爲實現代碼如下出現在屏幕上後,才和它只有在實現代碼如下看來您填充stories

-(void)viewDidAppear:(BOOL)animated { 

    [super viewDidAppear:animated]; 

    if([stories count] == 0){ 
     NSString *path = @"http://feeds.feedburner.com/TheAppleBlog"; 

     [self parseXMLFileAtURL:path];  
    } 

    cellSize = CGSizeMake([newsTable bounds].size.width, 60); 

} 

然而,沒有觸發的tableview再次致電numberOfRowsInSection這樣的tableview保持空白。只需將故事填入viewWillAppear:即可解決問題。

每當您更改tableview所依賴的數據時(無論原因如何),您必須調用reloadData,否則tableview將不會意識到它不再顯示當前數據集。

另外,在引用屬性時應該使用點符號以確保它們被正確保留。您應該使用self.stories來指代stories屬性。否則,它可能會隨機釋放,導致同樣的隨機崩潰。

+0

非常感謝您的建議。但是,你能告訴我,我怎樣才能移動「故事人羣」的觀點來看待將會如何:? –

+0

我的意思是把'故事'相關代碼移動到'viewDidAppear'。更好的是,只需在'viewDidAppear'中調用'[newsTable reloadData];''。這將導致tableview重新加載它的數據,並在'stories'數組填充後重繪自己***。 – TechZen

相關問題