deleteRowsAtIndexPaths导致SIGABRT

时间:2014-10-27 09:47:23

标签: objective-c xcode uitableview sigabrt

我已经阅读了很多帖子,但无法找到答案。 我在我的项目MGSwipeTableCell中添加了https://github.com/MortimerGoro/MGSwipeTableCell

我添加了.h文件:#import "MGSwipeTableCell.h""MGSwipeButton.h"

还补充说:

@interface BuyItemListViewController : UIViewController <NSFetchedResultsControllerDelegate, MGSwipeTableCellDelegate, UITableViewDelegate, UITableViewDataSource, UIActionSheetDelegate>

在storyboard中,我将MGSwipeTableCell类设置为我的单元格。正如在这个自定义控件的帮助下所写。

所以,当我尝试使用我的自定义按钮删除行时,获取该deleteRowsAtIndexPaths会导致SIGABRT:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections]objectAtIndex:section];
    return [sectionInfo numberOfObjects];
    //return self.fetchedResultsController.fetchedObjects.count;
}

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{

    return YES;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *cellIdentifier = @"itemCell";
    MGSwipeTableCell *cell = [self.itemTableView dequeueReusableCellWithIdentifier:cellIdentifier];

    cell.leftSwipeSettings.transition = MGSwipeTransitionBorder;
    cell.rightSwipeSettings.transition = MGSwipeTransitionBorder;

    cell.leftButtons = [self createLeftButtons:1];
    cell.rightButtons = [self createRightButtons:1];

    cell.delegate = self;

    BuyItemEntity *item = [self.fetchedResultsController objectAtIndexPath:indexPath];

    [self applyCellValues:cell :item];

    return cell;

}

错误在此代码中:

-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion
{

    NSLog(@"Delegate: button tapped, %@ position, index %d, from Expansion: %@",
          direction == MGSwipeDirectionLeftToRight ? @"left" : @"right", (int)index, fromExpansion ? @"YES" : @"NO");

    if (direction == MGSwipeDirectionRightToLeft && index == 0) {
        //delete button
        NSIndexPath * path = [_itemTableView indexPathForCell:cell];
        NSLog(@"indexpath swipe: %i", path.row);

        NSManagedObjectContext *context = [self managedObjectContext];
        BuyItemEntity *itemToDelete = [self.fetchedResultsController objectAtIndexPath:path];
        [context deleteObject:itemToDelete];

        NSError *error = nil;
        if(![context save:&error]){NSLog(@"Eror TableView deleting! %@", error);} //---the object delete correctly

        [_itemTableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft]; // here is SIGABRT

        NSLog(@"Delete button pressed");

    }

但是在这个类的Demo应用程序中没有问题,来自Demo的代码:

-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion
{

    NSLog(@"Delegate: button tapped, %@ position, index %d, from Expansion: %@",
          direction == MGSwipeDirectionLeftToRight ? @"left" : @"right", (int)index, fromExpansion ? @"YES" : @"NO");

    if (direction == MGSwipeDirectionRightToLeft && index == 0) {
        //delete button
        NSIndexPath * path = [_tableView indexPathForCell:cell];
        [tests removeObjectAtIndex:path.row];
        [_tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
        NSLog(@"Delete button pressed");
    }

    return YES;

}

我在调试选项中启用了Zombie Object以获取更多信息。

http://s020.radikal.ru/i700/1410/3d/f63fbedbcff7.png

Convenience callback received (right).
2014-10-27 12:11:22.576 NotesApp_1[4885:247508] Delegate: button tapped, right position, index 0, from Expansion: NO
2014-10-27 12:11:22.576 NotesApp_1[4885:247508] indexpath swipe: 2
2014-10-27 12:11:22.580 NotesApp_1[4885:247508] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1314
2014-10-27 12:11:22.585 NotesApp_1[4885:247508] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 2 from section 0 which only contains 2 rows before the update'
*** First throw call stack:
(
    0   CoreFoundation                      0x0206d946 __exceptionPreprocess + 182
    1   libobjc.A.dylib                     0x01cf6a97 objc_exception_throw + 44
    2   CoreFoundation                      0x0206d7da +[NSException raise:format:arguments:] + 138
    3   Foundation                          0x0196a810 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 118
    4   UIKit                               0x007c3f56 -[UITableView _endCellAnimationsWithContext:] + 4313
    5   UIKit                               0x007dc421 -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] + 337
    6   UIKit                               0x007dc49f -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] + 56
    7   NotesApp_1                          0x000587dd -[BuyItemListViewController swipeTableCell:tappedButtonAtIndex:direction:fromExpansion:] + 749
    8   NotesApp_1                          0x0005f815 -[MGSwipeButtonsView handleClick:fromExpansion:] + 789
    9   NotesApp_1                          0x0005f9bc -[MGSwipeButtonsView buttonClicked:] + 108
    10  libobjc.A.dylib                     0x01d0c7cd -[NSObject performSelector:withObject:withObject:] + 84
    11  UIKit                               0x006cf23d -[UIApplication sendAction:to:from:forEvent:] + 99
    12  UIKit                               0x006cf1cf -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
    13  UIKit                               0x00802e86 -[UIControl sendAction:to:forEvent:] + 69
    14  UIKit                               0x008032a3 -[UIControl _sendActionsForEvents:withEvent:] + 598
    15  UIKit                               0x0080250d -[UIControl touchesEnded:withEvent:] + 660
    16  UIKit                               0x0071f60a -[UIWindow _sendTouchesForEvent:] + 874
    17  UIKit                               0x007200e5 -[UIWindow sendEvent:] + 791
    18  UIKit                               0x006e5549 -[UIApplication sendEvent:] + 242
    19  UIKit                               0x006f537e _UIApplicationHandleEventFromQueueEvent + 20690
    20  UIKit                               0x006c9b19 _UIApplicationHandleEventQueue + 2206
    21  CoreFoundation                      0x01f911df __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    22  CoreFoundation                      0x01f86ced __CFRunLoopDoSources0 + 253
    23  CoreFoundation                      0x01f86248 __CFRunLoopRun + 952
    24  CoreFoundation                      0x01f85bcb CFRunLoopRunSpecific + 443
    25  CoreFoundation                      0x01f859fb CFRunLoopRunInMode + 123
    26  GraphicsServices                    0x0501424f GSEventRunModal + 192
    27  GraphicsServices                    0x0501408c GSEventRun + 104
    28  UIKit                               0x006cd8b6 UIApplicationMain + 1526
    29  NotesApp_1                          0x0006af2d main + 141
    30  libdyld.dylib                       0x02883ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

在那段时间我的旧方法正常工作,而不使用自定义单元格类:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{


    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        //[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        NSManagedObjectContext *context = [self managedObjectContext];

        BuyItemEntity *itemToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];

        [context deleteObject:itemToDelete];

        NSError *error = nil;

        if(![context save:&error]){
            NSLog(@"Eror TableView deleting! %@", error);
        }

    }

}

1 个答案:

答案 0 :(得分:0)

你不在bounds。第一行的索引为0,因此2行以索引0开头,以索引1结束。