Как я могу инициализировать свойство класса, которое зависит от аргумента инициализатора, а также от `self`? - PullRequest
1 голос
/ 09 июля 2019

Я новый разработчик Swift. Существует ли подходящий шаблон для инициализации переменной класса, инициализатор которой требует ссылку на self?

Пример кода:

class Consumer
{
    var supplier: Supplier;

    init(observer: Observer)
    {
        // error: 'self' used before all stored properties are initialized
        self.supplier = Supplier(observer: observer, consumer: self);
    }
}

class Observer {}

class Supplier
{
    init(observer: Observer, consumer: Consumer) {/*do init*/}
}

Я могу сделать свойство явно развернутым необязательным, но мне это кажется неправильным, потому что я не хочу нести расходы, связанные с необязательными (эта переменная будет доступна в узком цикле). Это предположение неверно? Предоставляют ли явно развернутые опции производительность, сопоставимую с обычной var, или они все еще проверяются при доступе?

class Consumer
{
    var supplier: Supplier!; // explicitly unwrapped Optional

    init(observer: Observer)
    {
        /*
        pro: problem solved
        con?: accessing supplier incurs the costs of accessing an Optional?
        */
        self.supplier = Supplier(observer: observer, consumer: self);
    }
}

/*other classes*/

У меня может быть дополнительная переменная, чтобы сначала инициализировать класс, а затем ленивая переменная, чтобы можно было использовать self, но затем я храню дополнительную переменную в классе, которая на самом деле не нужна после инициализации.

class Consumer
{
    var observer: Observer; // never used elsewhere after initialization
    lazy var supplier: Supplier = Supplier(observer: observer, consumer: self);

    init(observer: Observer)
    {
        /*
        pro: problem solved
        con: small memory overhead
        */
        self.observer = observer;
    }
}

/*other classes*/

ПРИМЕЧАНИЕ: Я не ищу совета по ссылочным циклам зависимостей, просто по поводу заявленной проблемы.

1 Ответ

3 голосов
/ 09 июля 2019

Альтернативой является объявление consumer в Supplier как weak optional, чтобы избежать цикла сохранения (Consumer содержит строгое указание на Supplier и наоборот)

class Consumer
{
    let supplier: Supplier

    init(observer: Observer)
    {
        self.supplier = Supplier(observer: observer)
        supplier.consumer = self
    }
}

class Observer {}

class Supplier
{
    let observer : Observer
    weak var consumer : Consumer?

    init(observer: Observer, consumer: Consumer? = nil) {
        self.observer = observer
        self.consumer = consumer
    }
}

Иэто Свифт: без запятой.

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