се срива в Xcode версия 4.2 и iOS 5 (издаден на 12 октомври 2011 г.) при [self.tableview reload data]

внедрявах табличния изглед програмно, където зададох свойството на 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];  

}

didSelectRowAtIndex

- (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-statement в mSelectedsubunitindex.row, когато превъртам, но разреших само проверката, че if (indexPath.row){}, а също така редът остава избран, когато върна лошо към моя контролер за tableview

- (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.--- се грижи за това, ако свойството е маркирано retain. В противен случай (или ако не е собственост) трябва да запазите/освободите себе си - 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