Swift соответствует протоколу подкласса - PullRequest
2 голосов
/ 29 июня 2019

В моем приложении есть несколько подклассов UIView, которые зависят от модели. Каждый из классов принимает протокол «Restorable», который содержит суперкласс модели. Каждая подмодель описывает специфические необычные свойства UIView.

// Super-model
public protocol StoryItem {
    var id: Int64? { get }
}

// Parent protocol
public protocol Restorable: AnyObject {
    var storyItem: StoryItem? { get set }
}

// Specific protocol
public struct TextItem: StoryItem {
    public var id: Int64?
    public var text: String?
}

// Not complling
class ResizableLabel: UILabel, Restorable {
    var storyItem: TextItem?
}

Я получаю следующую ошибку компилятора:

*Type 'ResizableLabel' does not conform to protocol 'Restorable'*

Единственный способ заставить его скомпилироваться - это изменить ResizableLabel на

// Works
class ResizableLabel: UILabel, Restorable {
    var storyItem: StoryItem?
}

Есть ли способ соответствовать подклассу протокола? это сделает процесс Init намного чище. Спасибо за вашу помощь!

1 Ответ

2 голосов
/ 29 июня 2019

Измените

public protocol Restorable: AnyObject {
    var storyItem: StoryItem? { get set } // adopter must declare as StoryItem
}

на

public protocol Restorable: AnyObject {
    associatedtype T : StoryItem
    var storyItem: T? { get set } // adopter must declare as StoryItem adopter
}

Теперь ваш код компилируется.Полный пример:

public protocol StoryItem {
    var id: Int64? { get }
}
public protocol Restorable: AnyObject {
    associatedtype T : StoryItem
    var storyItem: T? { get set }
}
public struct TextItem: StoryItem {
    public var id: Int64?
    public var text: String?
}
class ResizableLabel: UILabel, Restorable {
    var storyItem: TextItem? // ok because TextItem is a StoryItem adopter
}

...