尝试滚动时UITableView崩溃

时间:2010-04-05 13:21:47

标签: iphone xcode uitableview delegates

我在UITableView中遇到数据问题。我有UIViewController,它包含UITableView插座以及我正在使用的更多东西......它可以工作:) ...它很可爱,但是......

我创建了一个RSS阅读器类,它使用委托将数据部署到表中......再一次,如果我只是在主控制器中创建虚拟数据,一切正常!

问题在于这一行:rss.delegate = self;

预览看起来有点破碎,而不是Google代码上的那些RSS阅读器文件:

Link to the header file on GoogleCode

Link to the implementation file on Google code

我的控制器的viewDidLoad函数:

IGDataRss20 *rss = [[[IGDataRss20 alloc] init] autorelease];
rss.delegate = self;
[rss initWithContentsOfUrl:@"http://rss.cnn.com/rss/cnn_topstories.rss"];

和我的委托方法:

- (void)parsingEnded:(NSArray *)result {
    super.data = [[NSMutableArray alloc] initWithArray:result];
    NSLog(@"My Items: %d", [super.data count]);
    [super.table reloadData];
    NSLog(@"Parsing ended");
}

- (void)parsingError:(NSString *)message {
    NSLog(@"MyMessage: %@", message);
}

- (void)parsingStarted:(NSXMLParser *)parser {
    NSLog(@"Parsing started");
}

只是为了澄清,NSLog(@“Parsing结束”);正在执行,我在阵列中有10个项目。

希望有人能够帮助我,因为我变得非常绝望,我以为我不是这样的新手:)

谢谢,

的Ondrej

我的标题文件(表格控制器)的完整副本

WGTempTableController类是带有表插座,数据阵列等的UIViewController ......

//
//  CRFeedController.h
//  czReader
//
//  Created by Ondrej Rafaj on 5.4.10.
//  Copyright 2010 Home. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "WGTempTableController.h"
#import <IGDataRss20.h>


@interface CRFeedController : WGTempTableController <IGDataRss20Delegate> {

    //NSString *startUrl;

}

@end

我的实施文件(表格控制器)的完整副本

所有其他函数,如numberOfSectionsInTableView或numberOfRowsInSection都在WGTempTableController中

//
//  CRFeedController.m
//  czReader
//
//  Created by Ondrej Rafaj on 5.4.10.
//  Copyright 2010 Home. All rights reserved.
//

#import "CRFeedController.h"
#import "WGTempCell.h"


@implementation CRFeedController

- (void)viewDidLoad {
    [super viewDidLoad];
    IGDataRss20 *rss = [[[IGDataRss20 alloc] init] autorelease];
    rss.delegate = self;
    [rss initWithContentsOfUrl:@"http://rss.cnn.com/rss/cnn_topstories.rss"];
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)parsingEnded:(NSArray *)result {
    super.data = [[NSMutableArray alloc] initWithArray:result];
    NSLog(@"My Items: %d", [super.data count]);
    [super.table reloadData];
    NSLog(@"Parsing ended");
}

- (void)parsingError:(NSString *)message {
    NSLog(@"MyMessage: %@", message);
}

- (void)parsingStarted:(NSXMLParser *)parser {
    NSLog(@"Parsing started");
}

- (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.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

#pragma mark Table view

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MyCell";
    WGTempCell *cell = (WGTempCell *) [table dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CRFeedCell" owner:nil options:nil];
        for(id currentObject in topLevelObjects) {
            if([currentObject isKindOfClass:[WGTempCell class]]) {
                cell = (WGTempCell *) currentObject;
                break;
            }
        }
    }
    NSDictionary *d = [super.data objectAtIndex:indexPath.row];
    [[cell cellTitle] setText:[d objectForKey:@"title"]];
    return cell;
}



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


@end

我的标头文件(RSS阅读器)的完整副本

//
//  IGDataRss20.h
//  IGFrameworkProject
//
//  Created by Ondrej Rafaj on 4.4.10.
//  Copyright 2010 Home. All rights reserved.
//

#import <Foundation/Foundation.h>

@class IGDataRss20;

@protocol IGDataRss20Delegate <NSObject>

@optional

- (void)parsingStarted:(NSXMLParser *)parser;

- (void)parsingError:(NSString *)message;

- (void)parsingEnded:(NSArray *)result;

@end


@interface IGDataRss20 : NSObject {

    NSXMLParser *rssParser;
    NSMutableArray *data;

    NSMutableDictionary *currentItem;

    NSString *currentElement;

    id <IGDataRss20Delegate> delegate;

}

@property (nonatomic, retain) NSMutableArray *data;

@property (nonatomic, assign) id <IGDataRss20Delegate> delegate;


- (void)initWithContentsOfUrl:(NSString *)rssUrl;

- (void)initWithContentsOfData:(NSData *)inputData;


@end

我的实施文件(RSS阅读器)的完整副本

//
//  IGDataRss20.m
//  IGFrameworkProject
//
//  Created by Ondrej Rafaj on 4.4.10.
//  Copyright 2010 Home. All rights reserved.
//

#import "IGDataRss20.h"


@implementation IGDataRss20

@synthesize data, delegate;

- (void)initWithContentsOfUrl:(NSString *)rssUrl {
    self.data = [[NSMutableArray alloc] init];
    NSURL *xmlURL = [NSURL URLWithString:rssUrl];
    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [rssParser setDelegate:self];
    [rssParser setShouldProcessNamespaces:NO];
    [rssParser setShouldReportNamespacePrefixes:NO];
    [rssParser setShouldResolveExternalEntities:NO];
    [rssParser parse];
}

- (void)initWithContentsOfData:(NSData *)inputData {
    self.data = [[NSMutableArray alloc] init];
    rssParser = [[NSXMLParser alloc] initWithData:inputData];
    [rssParser setDelegate:self];
    [rssParser setShouldProcessNamespaces:NO];
    [rssParser setShouldReportNamespacePrefixes:NO];
    [rssParser setShouldResolveExternalEntities:NO];
    [rssParser parse];
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    [[self delegate] parsingStarted:parser];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSString * errorString = [NSString stringWithFormat:@"Unable to parse RSS feed (Error code %i )", [parseError code]];
    NSLog(@"Error parsing XML: %@", errorString);
    if ([parseError code] == 31) NSLog(@"Error code 31 is usually caused by encoding problem.");
    [[self delegate] parsingError:errorString];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    currentElement = [elementName copy];
    if ([elementName isEqualToString:@"item"]) currentItem = [[NSMutableDictionary alloc] init];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"item"]) {
        [data addObject:(NSDictionary *)[currentItem copy]];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (![currentItem objectForKey:currentElement]) [currentItem setObject:[[[NSMutableString alloc] init] autorelease] forKey:currentElement];
    [[currentItem objectForKey:currentElement] appendString:string];
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    //NSLog(@"RSS array has %d items: %@", [data count], data);
    [[self delegate] parsingEnded:(NSArray *)self.data];
}




- (void)dealloc {
    [data, delegate release];
    [super dealloc];
}

@end

2 个答案:

答案 0 :(得分:5)

当您尝试滚动时,您的主题说它崩溃了。我不知道这与你的rss.delegate有什么关系,所以我只是忽略它并专注于可能的滚动相关错误,这些错误通常在tableView:cellForRowAtIndexPath:。

  1. 检查您的CRFeedCell.xib,查看WGTempCell对象的信息,并确保其Identifier字段与您代码中的CellIdentifier匹配。 ( “了myCell”)

  2. 确保您没有将相同的CellIdentifier用于代码中其他位置的其他UITableViewCell子类。

  3. 是什么样的撞车?如果是EXC_BAD_ACCESS,请双击您的可执行文件,转到Arguments,创建一个NSZombieEnabled环境变量,并将其设置为YES。 (在完成调试时取消选中它以避免泄漏内存。)这将显示您在应用程序崩溃时尝试访问的对象。

  4. 在tableView:setForRowAtIndexPath:中的setText:call上设置断点。然后在你的gdb提示符下输入po [d objectForKey:@“title”]。确保该对象确实是一个NSString。

答案 1 :(得分:0)

在我看来,好像你初始化两次NSMutableArray数据:首先在initWithContentsOfUrl:中,然后再次在parsingEnded中:。也许你应该在parsingEnded中做一个removeAllObjects。