Можно ли инициализировать переменную в зависимости от другого в классе, наследуя от UIViewController в Swift? - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь достичь, казалось бы, простой вещи: инициализировать постоянную переменную, используя другую из того же класса, которая наследуется от UIViewController. У меня было 2 идеи, которые сработали, но у них есть свои проблемы, и они, похоже, не являются лучшим решением.

Идея 1 - проблема: не является постоянной

class MyViewController: UIViewController {
    let db = Firestore.firestore()
    let uid: String = UserDefaults.standard.string(forKey: "uid")!
    lazy var userDocRef = db.collection("users").document(uid)
}

Идея 2 - проблема : не является константой и является необязательной

class MyViewController: UIViewController {
    let db = Firestore.firestore()
    let uid: String = UserDefaults.standard.string(forKey: "uid")!
    var userDocRef: DocumentReference?
    override func viewDidLoad() {
        super.viewDidLoad()
        userDocRef = db.collection("users").document(uid)
    }
}

Я думаю, что можно добиться этого путем переопределения init(). Я перепробовал несколько реализаций, которые нашел Googling, но все, кого я пробовал, давали мне какую-то ошибку. Несколько примеров:

Из этого ответа.

convenience init() {
    self.init(nibName:nil, bundle:nil) // error: Argument passed to call that takes no arguments
    userDocRef = db.collection(K.Firestore.usersCollection).document(uid)
}

Из этой статьи.

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)! // Property 'self.userDocRef' not initialized at super.init call
}

init() {
   super.init(nibName: nil, bundle: nil) // Property 'self.userDocRef' not initialized at super.init call
   userDocRef = db.collection(K.Firestore.usersCollection).document(uid)
}

Я Угадай, я либо что-то упустил, или они устарели? Я удивлен такой простой задачей, поскольку переопределение инициализатора является такой проблемой. Как правильно это сделать?

1 Ответ

2 голосов
/ 02 мая 2020

Ваша вторая попытка довольно близка. Вы действительно просто пропустили это правило, которому нужно следовать:

все свойства, объявленные в вашем классе, должны быть инициализированы перед вызовом super.init.

В вашем вторая попытка, userDocRef не инициализируется в init(coder:) и инициализируется после a super.init вызова в init().

Вы должны написать это так:

init() {
    userDocRef = db.collection(K.Firestore.usersCollection).document(uid)
    super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
    userDocRef = db.collection(K.Firestore.usersCollection).document(uid)
    super.init(coder: coder)
}

Я не думаю, что вы можете избавиться от дублированного кода здесь ... Лучшее, что вы можете сделать, - это создать stati c вспомогательный метод, который возвращает db.collection(K.Firestore.usersCollection).document(uid), что означает db stati c, что может быть еще хуже, если подумать.

Обратите внимание, что все из раскадровок будет создано с использованием init(coder:), поэтому важно, чтобы вы сделали там также правильно инициализатор, если вы используете раскадровки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...