Почему быстрый компилятор выдает ошибку при выводе типа моего общего элемента, когда элемент явно ограничен? - PullRequest
0 голосов
/ 23 мая 2018

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

Ожидаемое поведение

Код должен компилироваться без ошибок.

Текущее поведение

Компилятор выдает два следующих ошибки:

  1. WeakRef требует этот элемент?быть типом класса
  2. Невозможно вывести тип для 'items'

Возможное решение

Единственное решение, которое я нашел, - сделать объекты свойств общедоступными и использоватьцикл for вместо методов расширения Collection.После этого компилятор смог определить тип для items, и даже методы Collection сработали.

Шаги для воспроизведения

Сначала реализуйте класс WeakRef:

final class WeakRef<T: AnyObject> {

    weak var value: T?

    init(_ value: T) {
        self.value = value
    }

}

Вторая реализация структуры WeakArray:

struct WeakArray<Element: AnyObject> {

    public var items: [WeakRef<Element>] = []

    init(_ elements: [Element]) {
        items = elements.map { WeakRef($0) }
    }
}

Третья реализация реализации расширения Collection:

extension WeakArray: Collection {

    var startIndex: Int { return items.startIndex }
    var endIndex: Int { return items.endIndex }

    subscript(_ index: Int) -> Element? {
        return items[index].value
    }

    func index(after idx: Int) -> Int {
        return items.index(after: idx)
    }

}

В-четвертых, создать экземпляр свойства WeakArray notоднако в том же исходном файле, что и WeakArray, например:

var objects: WeakArray<UIViewController> = WeakArray.init([])

Пятый и последний шаг вызывают метод протокола Collection, например:

objects.forEach({ $0?.view.backgroundColor = .white })

Context (Environment)

Этот код не будет компилироваться в версии Xcode Version 9.3.1 (9E501) с использованием Swift 4.1

Дополнительное описание

Решение для вышеуказанного кода найденопо следующим ссылкам:

  1. https://marcosantadev.com/swift-arrays-holding-elements-weak-references/
  2. https://www.objc.io/blog/2017/12/28/weak-arrays/

Заранее благодарим за любую предоставленную помощь.Это сообщение было полностью отредактировано, чтобы соответствовать стандартам Stackoverflow, задавая вопрос.Отдельное спасибо MartinR за то, что он помог мне опубликовать хороший вопрос о Stackoverflow.

1 Ответ

0 голосов
/ 24 мая 2018

A Collection имеет связанный тип Element, и это похоже на конфликт с вашим общим заполнителем Element.Использование другого имени E для заполнителя решает проблему:

struct WeakArray<E: AnyObject> {

    public var items: [WeakRef<E>] = []

    init(_ elements: [E]) {
        items = elements.map { WeakRef($0) }
    }
}

extension WeakArray: Collection {

    var startIndex: Int { return items.startIndex }
    var endIndex: Int { return items.endIndex }

    subscript(_ index: Int) -> E? {
        return items[index].value
    }

    func index(after idx: Int) -> Int {
        return items.index(after: idx)
    }
}
...