Расширение протокола, функция Mutating
Я использую swift 2.0, у меня есть протокол и расширение в протоколе, чтобы создать стандартную реализацию метода, код как паров:
protocol ColorImpressionableProtocol {
var lightAccentColor: UIColor? {get set}
var accentColor: UIColor? {get set}
var darkAccentColor: UIColor? {get set}
var specialTextColor: UIColor? {get set}
mutating func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?)
}
extension ColorImpressionableProtocol {
mutating func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?){
lightAccentColor = impresion?.lightAccentColor
accentColor = impresion?.accentColor
darkAccentColor = impresion?.darkAccentColor
specialTextColor = impresion?.specialTextColor
}
}
Позднее в моем коде пытается вызвать этот метод, и я получаю сообщение об ошибке:
"не может использовать мутирующий элемент в неизменяемом значении:" self "неизменен"
Код является парой:
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
Единственное, что я могу придумать, это то, что "Я" в этом случае является протоколом, а не классом. Однако мне нужно что-то упустить, чтобы эта концепция работала. Реализация по умолчанию метода, определенного протоколом, который редактирует значения, также определенные одним и тем же протоколом.
Спасибо за помощь и время:)
Ответы
Ответ 1
Если вы собираетесь использовать протокол только для классов, вы можете сделать
это протокол класса (и удалить ключевое слово mutating
):
protocol ColorImpressionableProtocol : class {
// ...
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?)
}
Тогда
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
компилируется без проблем.
Ответ 2
Вы принимаете этот протокол в классе, так что self (который является ссылочным типом) является неизменным. Компилятор ожидает, что self будет изменяемым с помощью изменяемого метода, объявленного в протоколе. Вот почему вы получаете эту ошибку.
Возможные решения:
1) Реализовать немутирующую версию метода, где протокол принимаются то есть: реализовать метод в принятии класса вместо расширение протокола.
class MyClass : ColorImpressionableProtocol {
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?){
lightAccentColor = impresion?.lightAccentColor
accentColor = impresion?.accentColor
darkAccentColor = impresion?.darkAccentColor
specialTextColor = impresion?.specialTextColor
}
}
2) Сделать протокол как протокол только для класса. Таким образом, мы можем удалить мутационное ключевое слово. Это самое простое решение, но его можно использовать только в классе.
Чтобы сделать класс протокола только:
protocol MyProtocolName : AnyObject { }
OR
protocol MyProtocolName : class { }
3) Убедитесь, что только типы значений принимают этот протокол. Это может быть бесполезно в все сценарии.
Здесь - подробное объяснение и решение для этого случая.