numberOfRowsInSection начинается с последнего раздела - PullRequest
0 голосов
/ 31 января 2010

На самом деле у меня очень простая проблема (это точно). Я просто не могу найти основную причину.

Проблема в том, что после вызова метода numberOfSectionsInTableView для получения количества разделов (в моем случае 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];
}

здесь идет число OfFowsInSection:

// 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];
 }

}

и ячейка ForRowAtIndexPath:

- (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 ]

2 голосов
/ 31 января 2010

У вас большая проблема с вашим cellForRowAtIndexPath. Доступ к CharsSpecial возможен независимо от того, в каком разделе вы находитесь (при условии, что в нем есть один элемент), и в нем может быть не так много элементов, как в этом разделе. Скорее всего, это является причиной аварии. Если ваш код хорошо написан, то таблица не по порядку не должна вылетать.

IndexPath состоит из двух компонентов: секции и строки. Чтобы получить нужные данные из 2D-массива, вы должны использовать [[topArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]. Аналогично, numberOfRows должно использовать [[topArray objectAtIndex:indexPath.section] count], а numberOfSections должно использовать [topArray count]. Таким образом, все эти методы согласованы. Вам нужно будет адаптировать это для словарей, но это должно быть тривиально.

Как только вы это сделаете и сможете прокрутить таблицу, опубликуйте новый вопрос о порядке ваших данных и включите весь код, который изменяет listOfItems.

Edit:

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) AlpineArray имеет утечку памяти, ее не следует сохранять, поскольку она уже была сохранена в alloc.

2) Любые разделы, которые вы хотите пропустить, должны быть удалены из AlphabetArray. По этой причине может быть лучше начать с пустого массива и добавить букву, когда вы доберетесь до этого оператора if (например, if ([charAArray count]> 0)).

3) В cellForRow вы, кажется, пытаетесь отобразить один элемент из каждого массива букв в каждой ячейке таблицы. Это твое намерение? Причина, по которой вы видите только последнее значение, заключается в том, что вы продолжаете изменять текст вашей метки (если у charAArray есть какие-либо объекты, он перезаписывает значение charSpecicalArray set). Я подозреваю, что вы действительно хотите использовать код, который я опубликовал выше, чтобы выбрать один массив, затем использовать строку 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 голос
/ 31 января 2010

У меня еще не было кофе, но я не понимаю, как это будет компилироваться.

Эта строка:

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

предположительно должно быть:

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

Обратите внимание на "s". У вас есть тип Char "charSpecial", когда вы хотели NSArray "charsSpecial". (Это не очень хорошие имена переменных, потому что они различаются только одной буквой в середине. Я предлагаю изменить "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.

Предположим, что где-то вы меняете свое порядковое (с нулевым индексом) значение на свое кардинальное (одно индексированное). Вы правильно запрашиваете имена разделов с порядковым значением, но выбираете строки с кардиналом. Поскольку кардинальное значение всегда на единицу больше порядкового, вы получаете ошибку выхода за границы.

Я думаю, вам следует рефракторить имена переменных и снова посмотреть на код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...