【问题标题】:Crash during UITableView moveRowAtIndexPath methodUITableView moveRowAtIndexPath 方法期间崩溃
【发布时间】:2011-02-21 09:30:26
【问题描述】:

我有一个字符串数组,已经在我的 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];
}

任何想法为什么它认为我正在尝试访问不存在的东西?

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

谢谢

【问题讨论】:

    标签: iphone uitableview ios4 crash nsmutablearray


    【解决方案1】:

    当您从数组中删除对象时,它会被释放,因此它的保留计数很可能会变为 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];
    

    【讨论】:

      【解决方案2】:

      我已经像你一样尝试过,但它无疑会导致崩溃,因为我认为如果数据源方法中有更多代码行(根据我的观察),委托执行可能不会与用户移动行协作。实际上,当您移动行时,外观意味着仅在 UITableView 单元格中进行了调整,但在后台它的数据也在调整,因此有一些机会,例如当您移动一行时,它已经被移动了,但它的数据资源(如数组或字典中的任何内容都不会根据其移动进行调整,那么它会给您 EXE 错误访问 kk。

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

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

      在这个方法中使用这段代码,它会在不崩溃的情况下工作。

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

      【讨论】:

        【解决方案3】:

        在 TableView Delegate 方法中,使用您的 myStringArray(作为 TableView 数据源)进行以下操作

         - (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 文件中添加两个新的委托

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

        【讨论】:

          【解决方案4】:

          在 myStringsArray 声明中,写成 nsmutable arrary initwithObjects, , nil ],并确保 .h 文件中的属性是强的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-14
            • 2018-07-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-19
            • 2011-08-08
            相关资源
            最近更新 更多