在UITableView moveRowAtIndexPath方法期间崩溃

时间:2011-02-21 09:30:27

标签: iphone uitableview ios4 crash nsmutablearray

我有一系列字符串,我已经在我的uitableview中显示了。

当我的uitableview启用了编辑时,我正在尝试将字符串从第4行移到第3行,当我调试此代码时,我在代码的索引部分插入对象中获得EXC_BAD_ACCESS。

[myStringsArray insertObject:name atIndex:toIndexPath.row]; 

但是,如果我不调试并且只是构建和运行,我会打印以下行,然后它崩溃而没有在我的控制台中看到EXC_BAD_ACCESS。

NSLog(@"re-ordered myStringsArray array");

这是我的moveRowAtIndexPath方法的所有代码:

// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectoryPath = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectoryPath stringByAppendingPathComponent:@"MyStrings.plist"]; 

    //re-order array
    NSString *name = [myStringsArray objectAtIndex:fromIndexPath.row];
    [myStringsArray removeObjectAtIndex:fromIndexPath.row];
    [myStringsArray insertObject:name atIndex:toIndexPath.row];

    NSLog(@"re-ordered myStringsArray array");
    if([myStringsArray writeToFile:path atomically: YES]){NSLog(@"write succesful");}
    else {NSLog(@"write failed");}

    [myTable reloadData];
}

为什么它认为我试图访问那些不存在的东西?

纠正我,如果我错了,但我的可变数组已经分配,​​如果删除方法有效,为什么插入方法不起作用?

谢谢

4 个答案:

答案 0 :(得分:5)

当你从数组中删除对象时,它会被释放,所以很有可能它的保留计数变为0并且它被取消分配。为避免过早释放,您可以保留并释放您的对象:

NSString *name = [[myStringsArray objectAtIndex:fromIndexPath.row] retain];
[myStringsArray removeObjectAtIndex:fromIndexPath.row];
[myStringsArray insertObject:name atIndex:toIndexPath.row];
[name release];

或者更好地使用内置的NSMutableArray方法来交换您自己找到的对象:

[myStringsArray exchangeObjectAtIndex:fromIndexPath.row withObjectAtIndex:toIndexPath.row];

答案 1 :(得分:0)

我试过像你一样,但毫无疑问会造成崩溃,因为如果在数据源方法中有更多的代码行(从我的观察中),我认为委托执行可能不会与用户移动行合作。实际上当你移动行时,外观意味着只在UITableView单元格中进行了调整,但是在后面它的数据也在调整,所以有一些机会,例如当你移动一行它已经被移动但它的数据资源如数组或字典中的任何内容都不会根据其移动进行调整,那么它会给你EXE糟糕的访问权限。

所以代码应该在下面的方法中非常少,以确保它不会崩溃。

[myArray exchangeObjectAtIndex:fromIndexPath.row      withObjectAtIndex:toIndexPath.row];

在此方法中使用此代码,它可以正常工作而不会崩溃。

  • (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath

答案 2 :(得分:0)

在TableView Delegate方法中,使用myStringArray(作为TableView DataSource)执行以下操作

 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 
 {   
   NSString *name = [[myStringsArray objectAtIndex:sourceIndexPath.row] retain];
   [myStringsArray removeObjectAtIndex:sourceIndexPath.row];
   [myStringsArray insertObject:name atIndex:destinationIndexPath.row];
   [name release];
 }

在你的.h文件中添加两个新的Delegate,如下所示

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
{    
  return YES;
}

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
   toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath 
{
  return proposedDestinationIndexPath;
}

答案 3 :(得分:0)

在myString Array声明中,写成类似于nsmutablearray的initwithObjects,nil],并确保.h文件中的属性很强。