numberOfRowsInSection从最后一节开始

时间:2010-01-31 11:28:39

标签: iphone

实际上我有一个非常简单的问题(这是肯定的)我找不到根本原因。

问题是,在调用numberOfSectionsInTableView方法获取Sections的数量(在我的情况下为24)之后,方法numberOfRowsInSection被调用,但是最后一节(23)。

这会在滚动时导致超出范围的索引。

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

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

当我调用我的应用程序时,部分标题已正确设置为“#”,但数据显示所有“X”值。 此时我有31个“X”值。当我现在滚动到31行中的最后一行时,应用程序因索引失误而崩溃。

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

---编辑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 个答案:

答案 0 :(得分:2)

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

IndexPath有两个组件:section和row。为了从2D阵列中获取您想要的数据,您应该使用[[topArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]。同样,numberOfRows应使用[[topArray objectAtIndex:indexPath.section] count],numberOfSections应使用[topArray count]。这样,所有这些方法都是一致的。你需要对字典进行调整,但这应该是微不足道的。

完成后,您可以滚动表格,发布有关数据顺序的新问题,并包含修改listOfItems的所有代码。

编辑:

ListOfItems似乎只保存一个字典,这意味着你并不真正需要它。我建议使用数组而不是字典作为顶级容器,因为它会使numberOfRows更简单,但要使用它,您需要替换而不是封装字典。

如果您想继续使用字典作为顶级容器,那就没问题。您应该更改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]&gt; 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部分

答案 1 :(得分: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

建议您在某处使用基数(一个索引)交换序数(零索引)值。您正确地使用序数值查询节名称,但是您使用基数获取行。由于基数值总是比序数多一个,因此会出现超出界限的错误。

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