调用“deleteRowsAtIndexPaths”时如何解决UITableView中的SIGABRT

Posted

技术标签:

【中文标题】调用“deleteRowsAtIndexPaths”时如何解决UITableView中的SIGABRT【英文标题】:How can solve the SIGABRT in UITableView when calling the "deleteRowsAtIndexPaths" 【发布时间】:2012-03-28 03:15:03 【问题描述】:

我是ios开发的初学者。我用数据构建了一个 UITableView, 但是最后一行不是数据行,叫“加载更多项”。(这个显示名不好,我稍后会改,可能在我解决这个问题之后)

“加载更多项目”包括 2 个功能: 选择最后一行时,此表将自动追加 4 行。 再次选择时,这 4 行将被删除。并再次。

但是当我第二次选择“加载更多项目”时,出现“程序接收信号:'SIGABRT'”。

... ...
[self.tableView beginUpdates];
 // Error here, SIGABRT, EXC_BAD_INSTRUCTION
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
... ...

我在 Xcode 4.2.1, ios5 SDK 中构建了这个 xcode 项目,没有 ARC,但是在运行时出现了问题。这里在代码中给出:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 

return 1;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
return [posts count] + 1;

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath   
static NSString *postCellId = @"postCell";
static NSString *moreCellId = @"moreCell";
UITableViewCell *cell = nil;

NSUInteger row = [indexPath row];
NSUInteger count = [posts count];

if (row == count) 
    NSLog(@"%@ -  indexPath : %d",NSStringFromSelector(_cmd), [indexPath row]);
    
    cell = [tableView dequeueReusableCellWithIdentifier:moreCellId];
    if (cell == nil) 
        cell = [[[UITableViewCell alloc] 
                 initWithStyle:UITableViewCellStyleDefault 
                 reuseIdentifier:moreCellId] autorelease];
    
    
    cell.textLabel.text = @"Load more items...";
    cell.textLabel.textColor = [UIColor blueColor];
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
    
    
 else 

    cell = [tableView dequeueReusableCellWithIdentifier:postCellId];
    if (cell == nil) 
        cell = [[[UITableViewCell alloc] 
                 initWithStyle:UITableViewCellStyleSubtitle 
                 reuseIdentifier:postCellId] autorelease];
    

    Post *currentPost = [posts objectAtIndex:row];
    cell.textLabel.text = [currentPost postTitle];
    cell.textLabel.font = [UIFont systemFontOfSize:14];
    
    cell.detailTextLabel.text = [currentPost postDescr];
    cell.detailTextLabel.font = [UIFont systemFontOfSize:10];


return cell;

- (void)tableView:(UITableView *)tableView 
               didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
NSLog(@"%@",NSStringFromSelector(_cmd));

NSUInteger row = [indexPath row];
NSUInteger count = [posts count];

if (row == count) 
    
    if(SIMPLE_FLAG_INT==0)
        NSArray *newPosts = [feed detailPosts];
        NSUInteger newCount = [newPosts count];
        
        if (newCount) 
            
            [self.posts addObjectsFromArray:newPosts];
            [newPosts release];
            
            NSMutableArray *insertIndexPaths = [NSMutableArray array];
            for (NSUInteger item = count; item < count + newCount; item++) 
                
                [insertIndexPaths addObject:[NSIndexPath indexPathForRow:item 
                                                               inSection:0]];
            

                
            [self.tableView beginUpdates];  
            [self.tableView insertRowsAtIndexPaths:insertIndexPaths 
                                      withRowAnimation:UITableViewRowAnimationFade];
            [self.tableView endUpdates];
            
            SIMPLE_FLAG_INT = 1;
            
            
            [self.tableView scrollToRowAtIndexPath:indexPath 
                                  atScrollPosition:UITableViewScrollPositionNone animated:YES];
            
           
        
    else
        SIMPLE_FLAG_INT = 0;

        NSLog(@" ==> %d num of row in section 0 ",[self tableView:self numberOfRowsInSection:0]);


        NSMutableArray *deleteIndexPaths = [NSMutableArray array];
        [deleteIndexPaths addObject:[NSIndexPath indexPathForRow:6   inSection:0]];
        [deleteIndexPaths addObject:[NSIndexPath indexPathForRow:5   inSection:0]];
        [deleteIndexPaths addObject:[NSIndexPath indexPathForRow:4   inSection:0]];    
        [deleteIndexPaths addObject:[NSIndexPath indexPathForRow:3   inSection:0]];
        
        
        [self.tableView beginUpdates];
        // Error here, SIGABRT, EXC_BAD_INSTRUCTION
        [self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];  
        [self.tableView endUpdates];               
    
    
    NSIndexPath *selected = [self.tableView indexPathForSelectedRow];
    NSLog(@"%@ - indexPathForSelectedRow(selected row): %d",NSStringFromSelector(_cmd), [selected row]);
    if (selected) 
        [self.tableView deselectRowAtIndexPath:selected animated:YES];
    
    
 else 

    PostViewController *postController = [[PostViewController alloc] 
                                          initWithNibName:@"PostView" 
                                          bundle:nil];
    postController.post = [posts objectAtIndex:row];

    [[self navigationController] pushViewController:postController 
                                           animated:YES];
    [postController release];
 

这是控制台输出:

2012-03-28 02:20:22.059 Feeder[4577:bf03] tableView:didSelectRowAtIndexPath:

2012-03-28 02:20:22.064 Feeder[4577:bf03] tableView:didSelectRowAtIndexPath: - indexPathForSelectedRow(选定行): 7

2012-03-28 02:20:23.600 Feeder[4577:bf03] tableView:didSelectRowAtIndexPath:

2012-03-28 02:20:23.601 Feeder[4577:bf03] ==> 第 0 节中的 8 行

当前语言:自动;目前客观-c

2012-03-28 02:21:05.756 Feeder[4577:bf03] *** 断言失败 -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1448.89/UITableView.m:995

2012-03-28 02:21:05.758 Feeder[4577:bf03] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。行数更新后包含在现有节中的行数 (8) 必须等于更新前该节中包含的行数 (8),加上或减去从该节插入或删除的行数(0 插入,4 删除) .'

*** 首次抛出时调用堆栈:

(

0 CoreFoundation 0x00fd75a9 __exceptionPreprocess + 185

1 libobjc.A.dylib 0x0112b313 objc_exception_throw + 44

2 CoreFoundation 0x00f8fef8 +[NSException raise:format:arguments:] + 136

3 基础 0x008193bb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116

4 UIKit 0x00094e8b -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 8420

5 UIKit 0x000841e8 -[UITableView endUpdates] + 42

6 馈线 0x0000356b -[FeedViewController tableView:didSelectRowAtIndexPath:] + 1371

7 UIKit 0x0008db68 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140

8 UIKit 0x00083b05 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219

9 基础 0x0079d79e __NSFireDelayedPerform + 441

10 核心基础 0x00fb88c3 CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 19

11 CoreFoundation 0x00fb9e74 __CFRunLoopDoTimer + 1220

12 核心基础 0x00f162c9 __CFRunLoopRun + 1817

13 CoreFoundation 0x00f15840 CFRunLoopRunSpecific + 208

14 核心基础 0x00f15761 CFRunLoopRunInMode + 97

15 图形服务 0x00cd71c4 GSEventRunModal + 217

16 图形服务 0x00cd7289 GSEventRun + 115

17 UIKit 0x00024c93 UIApplicationMain + 1160

18 馈线 0x000027cd 主 + 125

19 馈线 0x00002745 开始 + 53

20 ??? 0x00000001 0x0 + 1

屏幕截图:

【问题讨论】:

【参考方案1】:

您可以将“加载更多项目...”添加到您的帖子数组中吗?

我这么说是因为在我看来问题是 numberOfRowsInSection 方法中的 return [posts count] + 1

我猜 deleteRowsAtIndexPaths 正在尝试检查删除后数组中的记录数,但它不匹配,因为方法 numberOfRowsInSection 中的“加一” .

【讨论】:

我已经更正了 numbeOfRowsInSection 方法。 “return [posts count]” 但似乎行不通。 “SIGABRT”程序仍然发生。

以上是关于调用“deleteRowsAtIndexPaths”时如何解决UITableView中的SIGABRT的主要内容,如果未能解决你的问题,请参考以下文章

在 iPhone 的 Objective-C 中在 (commitEditingStyle) 之外调用 (deleteRowsAtIndexPaths)

deleteRowsAtIndexPaths 重叠问题

iOS Swift:deleteRowsAtIndexPaths 崩溃 [重复]

deleteRowsATIndexPaths 崩溃 [重复]

动态更改数据源导致 deleteRowsAtIndexPaths:indexes 崩溃

无法将 tableView.deleteRowsAtIndexPaths 与 coreData 一起使用