动态强制转换失败

时间:2014-12-02 14:06:51

标签: swift uitableview

当我点击一个tableview单元格时,我的iOS应用程序迅速崩溃。这一切都是以编程方式完成的。 (手动segue除外)当我点击一个单元格时,我得到一个动态演员调用失败。

这与CoreData,我的segue或我的tableview有关吗?只有当我让segue工作时才出现错误。在将表和CoreData的相同代码与在Storyboard中创建的表和视图一起使用之前。 (didSelectRowAtIndex除外)然后一切正常。不幸的是,通过故事板进行操作不是应用程序其余部分的选项。

真的迷失在这里。如果需要,可以发布更多代码。

谢谢

这是我遇到崩溃的错误消息。

libswiftCore.dylib`swift_dynamicCastClassUnconditional:
0x1042679e0:  pushq  %rbp
0x1042679e1:  movq   %rsp, %rbp
0x1042679e4:  testq  %rdi, %rdi
0x1042679e7:  je     0x104267a1e               ; swift_dynamicCastClassUnconditional + 62
0x1042679e9:  movabsq $-0x7fffffffffffffff, %rax
0x1042679f3:  testq  %rax, %rdi
0x1042679f6:  jne    0x104267a1e               ; swift_dynamicCastClassUnconditional + 62
0x1042679f8:  leaq   0xb5109(%rip), %rax
0x1042679ff:  movq   (%rax), %rax
0x104267a02:  andq   (%rdi), %rax
0x104267a05:  nopw   %cs:(%rax,%rax)
0x104267a10:  cmpq   %rsi, %rax
0x104267a13:  je     0x104267a2d               ; swift_dynamicCastClassUnconditional + 77
0x104267a15:  movq   0x8(%rax), %rax
0x104267a19:  testq  %rax, %rax
0x104267a1c:  jne    0x104267a10               ; swift_dynamicCastClassUnconditional + 48
0x104267a1e:  leaq   0x36b3d(%rip), %rax       ; "Swift dynamic cast failed"
0x104267a25:  movq   %rax, 0xb4a2c(%rip)       ; gCRAnnotations + 8
0x104267a2c:  int3   
0x104267a2d:  movq   %rdi, %rax
0x104267a30:  popq   %rbp
0x104267a31:  retq   
0x104267a32:  nopw   %cs:(%rax,%rax)

这是我的相关代码(我认为)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier? == "update" {
            var selectedItem: NSManagedObject = myTodos[self.todoTableView.indexPathForSelectedRow()!.row] as NSManagedObject

            let IVC: TodoViewController = segue.destinationViewController as TodoViewController

            IVC.todoItem = selectedItem.valueForKey("todoItem") as String
            IVC.todoTime = selectedItem.valueForKey("todoTime") as NSDate

            IVC.existingTodo = selectedItem
        }
    }

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.performSegueWithIdentifier("update", sender: self)
        println("You selected a cell")

    }

使用更正后的代码进行修改: 问题是由尝试通过导航控制器传递segue引起的。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier? == "update" {
            var selectedItem: NSManagedObject = myTodos[self.todoTableView.indexPathForSelectedRow()!.row] as NSManagedObject

            let navVC = segue.destinationViewController as UINavigationController

            //let tableVC = navVC.viewControllers.first as YourTableViewControllerClass
            let IVC: TodoViewController = navVC.viewControllers.first as TodoViewController


            IVC.todoItem = selectedItem.valueForKey("todoItem") as String
            IVC.todoTime = selectedItem.valueForKey("todoTime") as NSDate

            IVC.existingTodo = selectedItem
        }
    }

更新:

let IVC: TodoViewController = (segue.destinationViewController as UINavigationController).viewControllers.first as TodoViewController

let IVC: TodoViewController = segue.destinationViewController.topViewController as TodoViewController

2 个答案:

答案 0 :(得分:2)

我在你的代码中看到了四个垂头丧气:

var selectedItem: NSManagedObject = myTodos[self.todoTableView.indexPathForSelectedRow()!.row] as NSManagedObject
let IVC: TodoViewController = segue.destinationViewController as TodoViewController
IVC.todoItem = selectedItem.valueForKey("todoItem") as String
IVC.todoTime = selectedItem.valueForKey("todoTime") as NSDate

我的猜测是错误是在最后两行中的一行 - 但我建议你在第一行放置一个断点并逐步执行代码 - 这将允许你找到实际产生错误的行。

答案 1 :(得分:1)

如果你的tableview控制器嵌入在UINavigationController中,那么segue.destinationViewController是一个UINavigationController实例,而不是TodoViewController实例。

您可能已经保留了导航控制器并替换了这一行:

let IVC: TodoViewController = segue.destinationViewController as TodoViewController

用这个:

let IVC: TodoViewController = segue.destinationViewController.topViewController as TodoViewController`

UINavigationController的.topViewController属性是指导航堆栈的顶部,应该是你的TodoViewController