Swift Managed Object Context Save 失败

Posted

技术标签:

【中文标题】Swift Managed Object Context Save 失败【英文标题】:Swift Managed Object Context Save failure 【发布时间】:2015-01-21 16:51:53 【问题描述】:

简单的应用程序从带有添加按钮的导航控制器中的表格视图开始。添加按钮会带来一个带有文本字段的新视图,单击保存会带您回到(更新的)表格视图。我的问题是当我尝试保存 MOC 时,什么也没有发生,并且应用程序在调试器中崩溃了:

First name is: John
Last name is: Doe
Phone number is: 123456789
Before Save
(lldb) 

和(****是它崩溃的那一行)

libswiftCore.dylib`swift_dynamicCastClassUnconditional:
0x10c385860:  pushq  %rbp
0x10c385861:  movq   %rsp, %rbp
0x10c385864:  testq  %rdi, %rdi
0x10c385867:  je     0x10c38589e               ; swift_dynamicCastClassUnconditional + 62
0x10c385869:  movabsq $-0x7fffffffffffffff, %rax
0x10c385873:  testq  %rax, %rdi
0x10c385876:  jne    0x10c38589e               ; swift_dynamicCastClassUnconditional + 62
0x10c385878:  leaq   0xb52e9(%rip), %rax
0x10c38587f:  movq   (%rax), %rax
0x10c385882:  andq   (%rdi), %rax
0x10c385885:  nopw   %cs:(%rax,%rax)
0x10c385890:  cmpq   %rsi, %rax
0x10c385893:  je     0x10c3858ad               ; swift_dynamicCastClassUnconditional + 77
0x10c385895:  movq   0x8(%rax), %rax
0x10c385899:  testq  %rax, %rax
0x10c38589c:  jne    0x10c385890               ; swift_dynamicCastClassUnconditional + 48
0x10c38589e:  leaq   0x36b7d(%rip), %rax       ; "Swift dynamic cast failed"
0x10c3858a5:  movq   %rax, 0xb4c0c(%rip)       ; gCRAnnotations + 8
0x10c3858ac:  int3   
****0x10c3858ad:  movq   %rdi, %rax
0x10c3858b0:  popq   %rbp
0x10c3858b1:  retq   
0x10c3858b2:  nopw   %cs:(%rax,%rax)

这是我的保存功能:

    @IBAction func save() 

    if let moc = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext 

        employee = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as Employee
        contact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: moc) as Contact
        employee.contact = contact

        //println("First name is: " + employee.contact.firstName)
        employee.contact.firstName = firstNameTextField.text
        println("First name is: " + employee.contact.firstName)

        employee.contact.lastName = lastNameTextField.text
        println("Last name is: " + employee.contact.lastName)

        employee.contact.phoneNumber = phoneNumberTextField.text
        println("Phone number is: " + employee.contact.phoneNumber)

        var e: NSError?
        println("Before Save")
        if moc.save(&e) != true 
            println("After Save")
            println("insert error: \(e!.localizedDescription)")
            return
        
        println("After Save")

    // Execute the unwind segue and go back to the home screen
    performSegueWithIdentifier("unwindToHomeScreen", sender: self)


更新

员工类:

import Foundation
import CoreData

class Employee: NSManagedObject 

    @NSManaged var wage: NSNumber
    @NSManaged var socialInsuranceNumber: NSNumber
    @NSManaged var contact: Contact


联系人类:

import Foundation
import CoreData

class Contact: NSManagedObject 

    @NSManaged var firstName: String
    @NSManaged var lastName: String
    @NSManaged var phoneNumber: String
    @NSManaged var employee: NSManagedObject


【问题讨论】:

请显示您的 Employee 和 Contact 托管对象子类。 为什么Contact-Classic 中有employee 变量?你没有在任何地方设置它。删除它,然后重试。 我不知道这是否足够,但您应该将 @NSManaged var employee: NSManagedObject 替换为以下行:@NSManaged var employee: Employee @c0dev 员工与联系人是一对一的。我的印象是,如果设置了关系的一端,另一端是自动设置的。 我不确定。但是将类中的类型从 NSManagedObject 更改为 Employee。 【参考方案1】:

我能够重现您的错误消息。您收到此消息是因为您没有在核心数据模型编辑器中正确设置实体类名称。

在核心数据模型编辑器中将您的实体类名称字段定义为<MyAppName>.Employee<MyAppName>.Contact

请参阅此previous answer 了解更多详情。您还可以了解有关 Core Data 和命名空间的更多信息here。

【讨论】:

奇数。我已经这样做了,但是 包含空格,所以我将它们替换为“_”(也尝试了“-”,就像您在 UNIX 中所做的那样)。将 MyApp 重命名为不包含空格可修复所有问题。当我有足够的代表时会排名。非常感谢您的宝贵时间。【参考方案2】:

您不能将NSManagedObject 投射到您的班级。

你必须这样做:

 employee = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as NSManagedObject

然后,您可以使用valueForKey-方法访问属性。

你也可以创建一个 NSManagedObject 类。这样就可以将其转换为此类。

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface Employee: NSManagedObject

@property (nonatomic, retain) NSString* firstName;
@property (nonatomic, retain) NSString* lastName;
@property (nonatomic, retain) NSString* phoneNumber;

@end

访问:

 employee = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as Employee

【讨论】:

以上是关于Swift Managed Object Context Save 失败的主要内容,如果未能解决你的问题,请参考以下文章

当 testes 函数调用 AppDelegate + managed Object 时单元测试崩溃

ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [object references

如果在 Windows 上使用 boost managed_shared_memory 则崩溃

Swift:在核心数据模型中搜索字符串

Object-C与Swift混合开发

Object-C与Swift混编