2010-01-31 56 views
0

其实我有一个非常简单的问题(这是肯定的),我找不到根本原因。numberOfRowsInSection从上一节开始

的问题是,在调用numberOfSectionsInTableView方法后得到(在我的案件24)节数的方法numberOfRowsInSection被调用但最后一节(23)。

滚动时会导致超出边界的索引。

那么,会发生什么? 我收到最后一节(23)的数据,甚至最后一节(23)的行数,之后各节向前移动,如0,1,2,3等...

举例: 我有一个节标题“#”的特殊字符。在我的情况下,最后一部分是以“X”开头的所有值的“X”。

当我打电话给我的应用程序时,节标题已被正确设置为“#”,但数据显示所有“X”值。 此时我有31个“X”值。当我滚动到31行的最后一行时,应用程序因为索引错误而崩溃。

我认为一切都会正常工作如果部分不会从最后一个开始,然后继续第一个(23,0,1,2,3,4等)。 我只是找不到地方或为什么该部分的价值23在第一个地方。

--- EDIT 2开始: 初始化数组:

alphabetArray = [[NSMutableArray alloc] init]; 

首先,我填补这样一个字典(所有字母含特殊字符。):

charDict = [[NSMutableDictionary alloc] init]; 

if ([charSpecialArray count] > 0) { 

    [charDict setObject:charSpecialArray forKey:@"Special"]; 
    [alphabetArray addObject:@"Special"]; 
} 

if ([charAArray count] > 0) { 

    [charDict setObject:charAArray forKey:@"A"]; 
    [alphabetArray addObject:@"A"]; 
} 

---编辑2结束

所以在这里,我只是用所有“#”值填充第一个字典对象(继续所有其他值)

然后我称之为numberOfSectionsInTableView方法:

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

这里numberOfRowsInSection云:

// Customize the number of rows in the table view. 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

NSString *key = [alphabetArray objectAtIndex:section]; 
NSArray *array = [charDict objectForKey:key]; 
return [array count]; 
} 

} 

和的cellForRowAtIndexPath:

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

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 


if(cell == nil) 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease]; 

if ([charSpecialArray count] > 0) { 

    Char *charSpecial = (Char *)[[charSpecialArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 

    cell.textLabel.numberOfLines = 1; 
    cell.detailTextLabel.numberOfLines = 2; 
    [cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize: 12]]; 

    cell.textLabel.text = charSpecial.ta; 
    cell.detailTextLabel.text = charSpecial.descriptionEN; 
} 

if ([charAArray count] > 0) { 

    Char *charA = (Char *)[[charAArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 

    cell.textLabel.numberOfLines = 1;   
      cell.detailTextLabel.numberOfLines = 2; 
    [cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize: 12]]; 

    cell.textLabel.text = charA.ta; 
    cell.detailTextLabel.text = charA.descriptionEN; 

    } 
再次对所有字符

...

任何建议如何解决这个问题?

添加 初始化代码.H:

#import <UIKit/UIKit.h> 

@interface Char : NSObject { 
NSString *ta; 
NSString *report; 
NSString *descriptionDE; 
NSString *descriptionEN; 
} 

@property (nonatomic, retain) NSString *ta; 
@property (nonatomic, retain) NSString *report; 
@property (nonatomic, retain) NSString *descriptionDE; 
@property (nonatomic, retain) NSString *descriptionEN; 


-(id)initWithTa:(NSString *)t report:(NSString *)re descriptionDE:(NSString *)dde  descriptionEN:(NSString *)den; 

@end 

初始化代码.M:

#import "SCode.h" 

@implementation Char 

@synthesize ta, report, descriptionDE, descriptionEN; 

-(id)initWithTa:(NSString *)t report:(NSString *)re descriptionDE:(NSString *)dde descriptionEN:(NSString *)den { 
self.ta = t; 
self.report = re; 
self.descriptionDE = dde; 
self.descriptionEN = den; 
return self; 
} 

- (void)dealloc { 

[ta release]; 
[report release]; 
[descriptionDE release]; 
[descriptionEN release]; 
[super dealloc]; 
} 

@end 

回答

2

您的cellForRowAtIndexPath存在很大问题。无论你在哪一部分(只要它有一个项目),CharsSpecial都可以被访问,并且它可能没有那一部分那样多的项目。这很可能导致崩溃。如果你的代码编写得很好,那么乱序表不应该使任何事情崩溃。

IndexPath有两个组件,分区和行。为了从二维数组中获得你想要的数据,你应该使用[[topArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]。同样,numberOfRows应该使用[[topArray objectAtIndex:indexPath.section] count],numberOfSections应该使用[topArray count]。这样,所有这些方法都是一致的。你需要适应这个词典,但这应该是微不足道的。

一旦你这样做了,你可以滚动表格,发布一个关于你的数据顺序的新问题,并且包括修改listOfItems的所有代码。

编辑:

LISTOFITEMS似乎只能持有一本词典,这意味着你并不真的需要它。我建议使用数组而不是字典作为顶级容器,因为它会使numberOfRows更简单,但要使用它,则需要替换字典,而不是封装字典。

如果您想继续使用字典作为顶级容器,那就OK了。您应该更改numberOfSections来计算字典中的项目数,而不是listOfItems数组。 NumberOfRows应该是这个样子:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    NSString *key = [sectionNameArray objectAtIndex:section]; 
    NSArray *array = [dictionary objectForKey:key]; 
    return [array count]; 
} 

哪里sectionNameArray是你使用的字典键的字符串数组(他们没有成为实际的节名)。

编辑2:

有几件事情:

1)alphabetArray有内存泄漏,你不应该保留它,因为它是已经通过保留ALLOC。

2)你想跳过的任何部分都需要从alphabetArray中移除。出于这个原因,最好从一个空数组开始,并在获得if语句时添加一个字母(例如if([charAArray count]> 0))。

3)在cellForRow中,您似乎试图在每个表格单元格中显示每个字母数组中的一个项目。这是你的意图吗?您只看到最后一个值的原因是因为您不断更改标签的文本(如果charAArray具有任何对象,则会覆盖charSpecicalArray集的值)。我怀疑你真正想要做的是使用我上面发布的代码来选择一个数组,然后使用indexPath行从该数组中选择一个项目,并使用该项目设置标签。它是否正确?

编辑3:

cellForRowAtIndexPath应该给予indexPath,不是所有的细胞表返回一个细胞。我不认为你正在修改你的来信阵列(你不应该),所以你要的是这样的:

NSString *key = [alphabetArray objectAtIndex:section]; 
NSArray *array = [charDict objectForKey:key]; 
Char *myChar = (Char *)[array objectAtIndex:indexPath.row]; 

cell.textLabel.numberOfLines = 1; 
cell.detailTextLabel.numberOfLines = 2; 
[cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize: 12]]; 

cell.textLabel.text = myChar.ta; 
cell.detailTextLabel.text = myChar.descriptionEN; 

这应全部更换if([array count] >0)部分的cellForRowAtIndexPath

+0

嗨大卫, 我改变了这样的代码: numberOfRowsInSection: NSDictionary * dictionary = [listOfItems objectAtIndex:section]; NSArray * array = [dictionary objectForKey:@“SCodes”]; return [array count]; numberOfSectionsInTableView: return [listOfItems count]; cellForRowAtIndexPath: SCode * searchSCodeSpecial =(SCode *)[[searchSCodesSpecial objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 不幸的是我收到以下错误: 2010-02-13 17:15:59.756 SCode [425:207] *** - [NSCFDictionary objectAtIndex:]:无法识别的选择器发送到实例0x76f5bc0 – Daniel 2010-02-13 16:23:28

+0

如果我不得不猜测,我会说charSpecial是一个字典,在cellForRowAtIndexPath中你可以调用objectAtIndex。 – 2010-02-13 17:43:05

+0

另外,你可以扩展初始化代码吗?看起来你添加了一个对象到一个字典,只有该字典到你的listOfItems,所以这个表只会有一个对象。它是否正确? – 2010-02-13 17:45:42

1

我还没有我的咖啡,但是我不认为这将如何连编译。

这条线:

Char *charSpecial = (Char *)[charSpecial objectAtIndex:indexPath.row]; 

应该大概是:

Char *charSpecial = (Char *)[charsSpecial objectAtIndex:indexPath.row]; 

注的 “S”。当你需要NSArray“charsSpecial”时,你有Char类型“charSpecial”。 (这些都不是很好的变量名,因为它们只是被埋在中间的单个字母区分,我建议将“charsSpecial”更改为“charSpecials”或更好的“charSpecilsArray”)。错误,因为它看起来更像是一个发布错误。你似乎这里有同样的问题:

if ([charSpecial count] > 0) { 

    NSDictionary *charsSpecialDict = [NSDictionary dictionaryWithObject:scodesSpecial forKey:@"Chars"]; 
    [listOfItems addObject:scodesSpecialDict]; 
} 

When I call my App, the section title has been set correctly to "#" but the data shows all the "X" values

建议您在某处将您的序数(零索引)与您的基数(一个索引)交换。您正确查询具有序号值的节名称,但是您正在用基数获取您的行。由于基数值总是比序数多一个,所以你会得到一个超出界限的错误。

我认为你应该折射你的变量名并再次查看代码。

+0

嗨TechZen , 正确的第一个是一个错字错误(只是试图匿名我的代码)。 可否请你给我一些关于序数和基数的更多信息? 逻辑清晰,但我无法将其分配给我的代码(抱歉我的英语不好)。 有可能给我一个特定的代码示例吗? – Daniel 2010-02-13 16:27:31