删除UITableView中的行会导致带有计算属性

时间:2015-06-09 04:13:45

标签: ios uitableview swift nsexception

我有一个计算属性作为实例变量:

var favorites: [PFObject]
    get { return Array(ObjectManager.favorites) }
}

其中ObjectManager.favoritesSet类上的ObjectManager静态变量。 以下是我的表格视图方法:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return favorites.count
}

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {

        //delete it from the original set
        ObjectManager.removeFavoriteObject(favorites[indexPath.row])

        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)


        println(favorites.count)
        // Delete the row from the data source

    }

    //If there are no longer any fav objects, then there is no need to display the Edit button.
    if favorites.isEmpty {
        self.navigationItem.rightBarButtonItem = nil
    }
}

这会导致在我调用deleteRowsAtIndexPaths时触发以下异常。

2015-06-08 21:00:35.320 MedConf[56258:707923] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3347.44/UITableView.m:1623
2015-06-08 21:00:35.396 MedConf[56258:707923] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001114aec65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000110defbb7 objc_exception_throw + 45
    2   CoreFoundation                      0x00000001114aeaca +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x0000000110a0498f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   UIKit                               0x0000000111b30c53 -[UITableView _endCellAnimationsWithContext:] + 12678
    5   UIKit                               0x0000000121f59f1b -[UITableViewAccessibility deleteRowsAtIndexPaths:withRowAnimation:] + 48
    6   MedConf                             0x000000010f1cebb3 _TFC7MedConf28FavoritesTableViewController9tableViewfS0_FTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 195
    7   MedConf                             0x000000010f1ced87 _TToFC7MedConf28FavoritesTableViewController9tableViewfS0_FTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 87
    8   UIKit                               0x0000000111b56226 -[UITableView animateDeletionOfRowWithCell:] + 132
    9   UIKit                               0x0000000111b353fd __52-[UITableView _swipeActionButtonsForRowAtIndexPath:]_block_invoke + 72
    10  UIKit                               0x0000000111a54da2 -[UIApplication sendAction:to:from:forEvent:] + 75
    11  UIKit                               0x0000000111b6654a -[UIControl _sendActionsForEvents:withEvent:] + 467
    12  UIKit                               0x0000000111b65919 -[UIControl touchesEnded:withEvent:] + 522
    13  UIKit                               0x0000000111dffa10 _UIGestureRecognizerUpdate + 9487
    14  UIKit                               0x0000000111aa1686 -[UIWindow _sendGesturesForEvent:] + 1041
    15  UIKit                               0x0000000111aa22b2 -[UIWindow sendEvent:] + 666
    16  UIKit                               0x0000000111a68581 -[UIApplication sendEvent:] + 246
    17  UIKit                               0x0000000111a75d1c _UIApplicationHandleEventFromQueueEvent + 18265
    18  UIKit                               0x0000000111a505dc _UIApplicationHandleEventQueue + 2066
    19  CoreFoundation                      0x00000001113e2431 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    20  CoreFoundation                      0x00000001113d82fd __CFRunLoopDoSources0 + 269
    21  CoreFoundation                      0x00000001113d7934 __CFRunLoopRun + 868
    22  CoreFoundation                      0x00000001113d7366 CFRunLoopRunSpecific + 470
    23  GraphicsServices                    0x0000000113603a3e GSEventRunModal + 161
    24  UIKit                               0x0000000111a53900 UIApplicationMain + 1282
    25  MedConf                             0x000000010f1debf7 main + 135
    26  libdyld.dylib                       0x0000000113bff145 start + 1
    27  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我不确定异常的原因是什么,因为即使我注释掉从数据源中移除对象的行,它也会被抛出:ObjectManager.removeFavoriteObject(favorites[indexPath.row])。 以下是removeFavoriteObject方法。

static func removeFavoriteObject( objectToRemove: PFObject ) {

    if contains(favorites, objectToRemove) {
        if let favObject = objectToRemove as? Attendee {
            favObject.isFavorite = false
        } else if let favObject = objectToRemove as? Event {
            favObject.isFavorite = false
        } else if let favObject = objectToRemove as? Session {
            favObject.isFavorite = false
        }
    }

    favorites.remove(objectToRemove)
}

3 个答案:

答案 0 :(得分:0)

试试这个

static func removeFavoriteObject( objectToRemove: PFObject ) {

if contains(favorites, objectToRemove) {
    favorites.remove(objectToRemove)
    if let favObject = objectToRemove as? Attendee {
        favObject.isFavorite = false
    } else if let favObject = objectToRemove as? Event {
        favObject.isFavorite = false
    } else if let favObject = objectToRemove as? Session {
        favObject.isFavorite = false
    }
}
}

答案 1 :(得分:0)

尝试将对象的索引传递给removeFavoriteObject静态方法:

ObjectManager.removeFavoriteObject(indexPath.row)

当你从favorites数组中传递元素索引时,它必须在那里。因此无需使用'if'进行检查。

static func removeFavoriteObject( index: Int ) {

   var objectToRemove = favorites[index]
   if let favObject = objectToRemove as? Attendee {
       favObject.isFavorite = false
   }
   else if let favObject = objectToRemove as? Event {
       favObject.isFavorite = false
   }
   else if let favObject = objectToRemove as? Session {
       favObject.isFavorite = false
   }

   favorites.removeAtIndex(index)
}

答案 2 :(得分:0)

tableview.beginUpdates()
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableview.endUpdates()

希望这有帮助