简体   繁体   中英

NSManagedObject Can't conform to protocol in Swift

I need a shared interface for a NSManagedObject and a regular NSObject. In Objective-c,I could use a protocol to achieve that. But in Swift i get this runtime error. Any Solution? Thanks in advance!

protocol Product { var code: String { get set } var sp: String { get set } }

class Stock: NSManagedObject, Product {

@NSManaged var code: String
@NSManaged var sp: String

}

Error: Undefined symbols for architecture i386: "__TFC11YellowPages5Stockg2spSS", referenced from: __TFC11YellowPages5Stockm2spSS in Stock.o "__TFC11YellowPages5Stockg4codeSS", referenced from: __TFC11YellowPages5Stockm4codeSS in Stock.o ld: symbol(s) not found for architecture i386 clang: error: linker command failed with exit code 1 (use -v to see invocation)

This worked for me. Try it for yourself and see if it works:

class MyEntity: NSManagedObject {

    @NSManaged var testAttribute: String
}

@objc
protocol MyProtocol {

    var testAttribute: String { get set }
}

extension MyEntity: MyProtocol { }

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let myContext = appDelegate.managedObjectContext!
        let entity: MyEntity = NSEntityDescription.insertNewObjectForEntityForName("MyEntity", inManagedObjectContext: myContext) as MyEntity
        foo(entity)
        println(entity.testAttribute)
    }

    func foo(var object: MyProtocol) {
        object.testAttribute = "bar"
    }
}

The below also worked, but I think the above is a better way to do it:

@objc
protocol MyProtocol {

    var testAttribute: String { get set }
}

class MyEntity: NSManagedObject, MyProtocol {

    @NSManaged var testAttribute: String
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let myContext = appDelegate.managedObjectContext!
        let entity: MyEntity = NSEntityDescription.insertNewObjectForEntityForName("MyEntity", inManagedObjectContext: myContext) as MyEntity
        foo(entity)
        println(entity.testAttribute)
    }

    func foo(var object: MyProtocol) {
        object.testAttribute = "bar"
    }
}

Swift

When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.

class Stock: NSManagedObject, Product {
    @NSManaged dynamic var code: String
    @NSManaged dynamic var sp: String
}

More on this here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM