сбой в Xcode версии 4.2 и iOS 5 (выпущен 12 октября 2011 г.) в [данные перезагрузки self.tableview]

я реализовал табличное представление программно, где я установил свойство mSelectedSubUnitIndex типа (NSIndexPath) как неатомарное и сохранил и синтезировал в .m . Когда я загружаю свой tableviewcontroller, метод:

(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath
:(NSIndexPath    *)indexPath
{
CGFloat height = 0.0;
    SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:indexPath.row];
NSArray *subUnitExercises = [self sortArray:[subUnit.subUnitExercise allObjects]];
  NSLog(@"mSelectedSubUnitIndex.row........%d",mSelectedSubUnitIndex.row);
NSLog(@"subUnitExercises........%d",[subUnitExercises count]);
  if (indexPath.row == mSelectedSubUnitIndex.row && [subUnitExercises count]>1) {
    height =CELL_EXPAND_HEIGHT ;
}
else {
    height = CELL_NORMAL_HEIGHT;
}
return height;   
} 

бегать вполне нормально. Когда я возвращаюсь к моему tableviewcontoller с другого контроллера, он падает (отправляет объектное сообщение) тем же методом в строке номер 5 в NSLog и выдает исключение в методе [self.tableView reloadData];. It is resolved by commenting[self.tableView reloadData];.

-(void)viewDidAppear:(BOOL)animated

{
DebugLog(@"start");
    //[self.tableview reloadData];

execountarray=[[NSMutableArray alloc]init];
for(int k=0;k<[mSubUnitsArray count];k++)
{
    SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:k];
    NSArray *subUnitExercises = [subUnit.subUnitExercise allObjects];
    [execountarray addObject:[NSString stringWithFormat:@"%d",[subUnitExercises  
    count]]];
}

///////////////
if (managedObjectContext){

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
entityForName:@"TSubUnitExerciseProgress" inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];

    // Order the events by creation date, most recent first.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
  initWithKey:@"editDate" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, 
    nil];
    [request setSortDescriptors:sortDescriptors];
    [sortDescriptor release];
    [sortDescriptors release];

    // Execute the fetch -- create a mutable copy of the result.
    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[managedObjectContext 
    executeFetchRequest:request error:&error] mutableCopy];
    if (mutableFetchResults == nil) {
        // Handle the error.
        myNotes = nil;
        [myNotes removeAllObjects]; 
    }
    else
    {
        [myNotes setArray: mutableFetchResults];
    }



    //NSLog(@"My notes count:--------unitviewcontroller--------------->%d", 
      [myNotes count]);
    if([myNotes count] ==0)
    {
    setExer1Done:NO;
    setExer2Done:NO;
    }
    else 
    {
        NSLog(@"hey :P");

    }

}
//  [self.tableview reloadData];  

}

сделалSelectRowAtIndex

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath 
*)indexPath 
{
DebugLog(@" -start- \n");
mSelectedSubUnitIndex = indexPath;
SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:indexPath.row];
NSArray *subUnitExercises = [self sortArray:[subUnit.subUnitExercise allObjects]];
if([subUnitExercises count]!=1) 
{
    NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:  
[mSelectedSubUnitIndex row] inSection:0]];
    [tableview beginUpdates];
    [tableview deleteRowsAtIndexPaths:paths   
withRowAnimation:UITableViewRowAnimationFade];
    [tableview insertRowsAtIndexPaths:paths  
withRowAnimation:UITableViewRowAnimationFade];
    [tableview endUpdates];
}
else
{
    //SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:  
[mSelectedSubUnitIndex row]];
    SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:indexPath.row];
    NSArray *subUnitExercises = [self sortArray:[subUnit.subUnitExercise 
 allObjects]];
    if ([subUnitExercises count] > 0) {
        SubUnitExercise *subUnitExercise = [subUnitExercises 
 objectAtIndex:0];
        [self loadSubUnitExercise:subUnitExercise];
    }
}
  }

это работает на iOS 4, но когда я собираю Xcode версии 4.2 и iOS 5 (выпущено 12 октября 2011 г.), происходит сбой. Не могу понять проблему. выручи меня!!

метод cellForRowAtIndex

теперь я получаю исключение в операторе if в mSelectedsubunitindex.row при прокрутке, но я решил только проверить, что если (indexPath.row) {}, а также строка остается выбранной, когда я возвращаю ошибку в свой контроллер таблицы

- (void)tableView:(UITableView *)tableView willDisplayCell:
 (UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
 {    
DebugLog(@"-start- \n");
SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:indexPath.row];
NSArray *subUnitExercises = [self sortArray:[subUnit.subUnitExercise allObjects]];
NSString *str1 = [[subUnit performSelector:@selector(title)]copy];
if ([str1 isEqualToString:@"1. was/were"]) 
{
    global = str1;
}
//if(indexPath.row==mSelectedSubUnitIndex.row)
if(indexPath.row)
    {

    if ([subUnitExercises count] != 1)
    {
      SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:            
      [mSelectedSubUnitIndex row]];
        NSArray *subUnitExercises = [self sortArray:
        [subUnit.subUnitExercise allObjects]];
        SubUnitCell *subUnitcell = (SubUnitCell*) cell;

        mCellSubTopicLabel.text = subUnit.title;

        if([myNotes count] == 0)
        {
            NSNumber *isDone = [[subUnitExercises objectAtIndex:1] isDone];

            [subUnitcell setExer2Done:NO];
            mExer2Checkbox.image = [UIImage imageNamed:[isDone boolValue]?   
            kExerciseCheckmark :kExerciseWrongmark];

            isDone = [[subUnitExercises objectAtIndex:0] isDone];
            [subUnitcell setExer1Done:NO];
            mExer1Checkbox.image = [UIImage imageNamed:[isDone boolValue]?
             kExerciseCheckmark :kExerciseWrongmark];

        }
        else 
        {
            NSNumber *isDone = [[subUnitExercises objectAtIndex:1] isDone];

            [subUnitcell setExer2Done:[isDone boolValue]];
            mExer2Checkbox.image = [UIImage imageNamed:[isDone boolValue]?
            kExerciseCheckmark :kExerciseWrongmark];
            isDone = [[subUnitExercises objectAtIndex:0] isDone];
            [subUnitcell setExer1Done:[isDone boolValue]];
            mExer1Checkbox.image = [UIImage imageNamed:[isDone boolValue]?
            kExerciseCheckmark :kExerciseWrongmark];        
        }
        [subUnitcell.contentView addSubview:mCellSubTopicContentView];

}

}

person Ketan Shinde    schedule 14.10.2011    source источник
comment
Что за крушение? Можете ли вы опубликовать трассировку стека?   -  person Robotic Cat    schedule 14.10.2011
comment
@RoboticCat: да, конечно! но весь этот код работает и в iOS 4 и 3   -  person Ketan Shinde    schedule 14.10.2011
comment
Можете ли вы также опубликовать метод cellForRowAtIndexPath? Также трассировка стека не помогает - можете ли вы добавить символический журнал сбоев?   -  person Robotic Cat    schedule 15.10.2011
comment
@RoboticCat: хорошо, я публикую метод cellForRowAtIndexPath.   -  person Ketan Shinde    schedule 18.10.2011


Ответы (2)


По какой-то причине назначение NSIndexPath (=) и равенство (==) не работает в IOS5. Я решил проблему, используя self перед любым объектом NSIndexPath, например.

self.mSelectedSubUnitIndex

Есть еще один способ решить это задание, используя копию следующим образом:

anIndexPath = (NSIndexPath*) [anotherIndexPath  copy];

Равенство работает точно так же. Нравится:

if([self.mSelectedSubUnitIndex isEqual:anotherIndexPath])
{

}
person suruz    schedule 31.10.2011
comment
Спасибо за помощь!! я использовал if([self.mSelectedSubUnitIndex isEqual:anotherIndexPath]) и сбой разрешился - person Ketan Shinde; 01.11.2011
comment
Вы должны сохранить индексный путь - self. --- позаботится об этом, если свойство помечено как сохранение. В противном случае (или если это не собственность) вы должны сохранить / освободить себя - person Oded Ben Dov; 12.11.2011

Только что быстро просмотрел ваш код. Меня бросают в глаза две вещи:

1: Самая последняя строка вашего tableView:cellForRowAtIndexPath: вызывает [self.tableview reloadData].

В этом нет необходимости, поскольку возвращаемая ячейка будет отображаться в том виде, в каком вы ее только что настроили. Также может показаться, что это вызовет цикл рисования («reloadData->cellForRowAtIndexPath->reloadData->cellForRowAtIndexPath-> и т. д.). Попробуйте удалить эту строку и посмотрите, решит ли это ваши проблемы.

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

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        /* Load a custom cell from a NIB
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
        cell = (UITableViewCell *)[nib objectAtIndex:0];
        */
        // Assume SubUnitCell exists somewhere
        SubUnitCell *cell = [[[SubUnitCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Retrieve config data and configure the cell as required in the code below - real config code needs to be added
    NSNumber *isDone = [NSNumber numberWithBool:NO];
    SubUnit *subUnit = (SubUnit*)[mSubUnitsArray objectAtIndex:[indexPath row]];

    [cell setTitle:subUnit.title];

    if([myNotes count] ==0)
    {
        [cell setExer1Done:NO];
        [cell setExer2Done:NO];
    }
    else
    {
        NSLog(@"My notes count:--------unitviewcontroller----->%d",[myNotes count]);    
    }

    // All your other configuration code
    .......
    .......
    .......

    return cell; 
}

Также попробуйте опубликовать символический журнал сбоев, чтобы люди могли увидеть точную ошибку и путь к ошибке.

person Robotic Cat    schedule 18.10.2011
comment
Я пошел с первым вариантом, но ничего не исправил. Он по-прежнему дает bad_access в методе viewdidappear при перезагрузке данных. - person Ketan Shinde; 19.10.2011
comment
когда я выбрал второй вариант, то есть dequeuereusablecellwithidentifier, тогда ячейка не отвечает на установленные методы заголовка и другие методы и т. д. Отображение предупреждений везде, где методы вызываются ячейкой. - person Ketan Shinde; 19.10.2011
comment
да, вы правы, я не хочу повторно использовать ячейку, но если вы предложили использовать dequeuereusablecellwithidentifier, тогда я пойду на это - person Ketan Shinde; 19.10.2011
comment
Я бы определенно использовал dequeueReusableCellWithIdentifier: и теперь давайте исправим, что метод setTitle не отвечает. Опубликуйте предупреждения, генерируемые компилятором (и статическим компилятором). Кроме того, где создается SubUnitCell - из NIB? - person Robotic Cat; 19.10.2011
comment
предупреждение было: ячейка может не отвечать на setTitle. но я решил это, заменив строку на SubUnitCell cell = (SubUnitCell)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; теперь, когда я возвращаюсь к контроллеру, строка остается выбранной, откуда я нажимаю новый контроллер. я публикую метод didSelectRowAtIndex, и SubUnitCell создается программно. - person Ketan Shinde; 20.10.2011
comment
Пожалуйста, скажите, когда вы будете доступны онлайн! - person Ketan Shinde; 20.10.2011
comment
Меня смущает, какая у вас проблема/ошибка и какой код был заменен. Вам нужно опубликовать новый вопрос с соответствующим кодом (вы также можете получить больше ответов, чем я). Но убедитесь, что объект SubUnitCell имеет свойство Title с установщиком/получателем. - person Robotic Cat; 20.10.2011