RealmSwift initializer: self used before super.init call

﹥>﹥吖頭↗ 提交于 2019-12-08 10:19:40

问题


import RealmSwift
import Realm

public class Card : Object {
    var username : String
    var firstName : String
    var lastName : String


    init?(dictionary: [String:Any]?) {
        guard let dictionary = dictionary , let username = dictionary["username"] as? String else { return else}

        self.username = username
        self.firstName = firstName 
        self.lastName = lastName
    }

    required public init() {
        fatalError("init() has not been implemented")
    }

    required public init( realm: RLMRealm, schema: RLMObjectSchema) {
        fatalError("init(realm:schema:) has not been implemented")
    }

    required public init( value: Any, schema: RLMSchema) {
       fatalError("init(value:schema:) has not been implemented")
    }
}

I get:

'self' used before super.init call

I had my class working properly. After adding RealmSwift i'm getting those errors. If I add super.init() it complains:

Property 'self.username' not initialized at super.init call


回答1:


There's a couple of things going on here.

First and foremost, when adding custom initializers to subclasses of Object, they must be declared as convenience initializers. It's not possible to correctly implement Object's required initializer from a subclass, and using a convenience initializer removes the need to try and do this. It also means you'll instead delegate to self.init() rather than super.init() from within your custom initializer.

Secondly, stored properties must have an initial value. Without the initial value the Swift compiler will not synthesize initializers for your class (in this case, a version of init() that calls through to the base class).

Finally, as I mentioned elsewhere, properties of type String must be declared using Swift's dynamic modifier to allow Realm to intercept get / set operations on them.

By following these guidelines you'll end up with something like so:

public class Card : Object {
    dynamic var username: String = ""
    dynamic var firstName: String = ""
    dynamic var lastName: String = ""

    convenience init?(dictionary: [String:Any]?) {
        guard let dictionary = dictionary,
            let username = dictionary["username"] as? String,
            let firstName = dictionary["firstName"] as? String,
            let lastName = dictionary["lastName"] as? String
            else { return nil }

        self.init()

        self.username = username
        self.firstName = firstName
        self.lastName = lastName
    }
}



回答2:


Because your properties are String.

From the apple docs...

Setting Initial Values for Stored Properties

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state. You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition. These actions are described in the following sections.

You have two options:

1)

var username : String = ""
var firstName : String = ""
var lastName : String = ""

2)

var username : String?
var firstName : String?
var lastName : String?


来源:https://stackoverflow.com/questions/44710340/realmswift-initializer-self-used-before-super-init-call

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!