【问题标题】:crashes in Xcode version 4.2 and iOS 5(released oct-12, 2011) at [self.tableview reload data]在 Xcode 4.2 版和 iOS 5(2011 年 10 月 12 日发布)中崩溃 [self.tableview reload data]
【发布时间】:2011-10-14 10:32:02
【问题描述】:

我正在以编程方式实现表视图,其中我将 (NSIndexPath) 类型的 mSelectedSubUnitIndex 属性设置为非原子并在 .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 时,它会在 NSLog 的第 5 行的相同方法处崩溃(发送对象消息),并在 [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(2011 年 10 月 12 日发布)构建时,它会崩溃。无法弄清楚问题所在。帮帮我!!

cellForRowAtIndex 方法

现在,当我滚动时,我在 mSelectedsubunitindex.row 的 if 语句中遇到异常,但我解决了只检查 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];

}

}

【问题讨论】:

  • 什么样的崩溃?你能发布堆栈跟踪吗?
  • @RoboticCat:是的,当然!但所有这些代码也在 iOS 4 和 3 中运行
  • 你也可以发布 cellForRowAtIndexPath 方法吗?堆栈跟踪也没有帮助 - 你可以添加符号化的崩溃日志吗?
  • @RoboticCat:好的,我正在发布 cellForRowAtIndexPath 方法。

标签: iphone ios5 xcode4.2


【解决方案1】:

由于某种原因 NSIndexPath 分配 (=) 和相等 (==) 在 IOS5 中不起作用。我已经在任何NSIndexPath 对象之前使用self 解决了这个问题,例如

self.mSelectedSubUnitIndex

还有另一种使用副本解决此分配的方法,如下所示:

anIndexPath = (NSIndexPath*) [anotherIndexPath  copy];

平等以同样的方式运作。喜欢:

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

}

【讨论】:

  • 感谢您的帮助!!我使用了 if([self.mSelectedSubUnitIndex isEqual:anotherIndexPath]) 并解决了崩溃
  • 您应该保留索引路径 - 如果属性标记为“保留”,“self.---”会处理此问题。否则(或者如果不是财产)你应该保留/释放自己
【解决方案2】:

刚刚快速浏览过您的代码。我突然想到两件事:

1:tableView:cellForRowAtIndexPath: 的最后一行调用[self.tableview reloadData]

这是不必要的,因为返回的单元格将按照您刚刚配置的方式显示。看起来这也会导致绘图循环(“reloadData->cellForRowAtIndexPath->reloadData->cellForRowAtIndexPath-> 等..)。尝试删除此行,看看是否可以解决您的问题。

2:您似乎没有重复使用细胞,尽管您的一个 cmets 似乎暗示您认为自己是。我希望方法的开头类似于下面的代码:

- (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; 
}

还请尝试发布符号化的崩溃日志,以便人们可以看到确切的错误和错误路径。

【讨论】:

  • 我选择了第一个选项,但没有解决任何问题。它仍然在重新加载数据时在 viewdidappear 方法中提供 bad_access。
  • 当我选择第二个选项时,即 dequeuereusablecellwithidentifier 然后单元格不响应设置标题方法和其他方法等。在单元格调用的方法处显示警告。
  • 是的,你说得对,我不想重复使用单元格,但如果你建议使用 dequeuereusablecellwithidentifier,那么我会这样做
  • 我肯定会使用 dequeueReusableCellWithIdentifier: 现在让我们修复 setTitle 方法没有响应。请发布编译器(和静态编译器)正在生成的警告。还有在哪里创建 SubUnitCell - 从一个NIB?
  • 警告是:“单元格可能不响应 setTitle。但我通过将行替换为 SubUnitCell cell = (SubUnitCell)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 现在解决了这个问题我导航回控制器,然后从我推送新控制器的位置保持选中行。我正在发布 didSelectRowAtIndex 方法,并且 SubUnitCell 是以编程方式创建的。
猜你喜欢
  • 1970-01-01
  • 2019-02-21
  • 2011-12-04
  • 1970-01-01
  • 2019-03-02
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多