iOS Swift4, как защитить вычисленное свойство, определенное в интерфейсе, от присвоения? - PullRequest
0 голосов
/ 26 августа 2018

Я отлаживаю некоторые плохо написанные модульные тесты для класса из унаследованной базы кода.Я вижу, что разработчик неправильно проверяет вычисляемое свойство.Я хочу понять, как заставить мои userEnabledFeature быть доступными только для чтения в классе Fake.

Почему протокол реализации класса с вычисляемым свойством может перезаписать вычисленное свойство и сделать его доступным для записи?

public protocol FeatureManager {
    var userEnabledFeature : Bool { get }
}

public class FakeFeatureManagerForTesting: FeatureManager {
    public var userEnabledFeature = false //is this legal? Why is compiler not complaining?

    public func updateUserEnabledFeature(enabled: Bool){
        //this should not be possible - how do I prevent overwriting computed property?
        userEnabledFeature = enabled
    }
}

ActualFeatureManagerClass {
    public var userEnabledFeature: Bool {
        if featureManager.cachedFeatures.filter { $0.enabled == true}
        {
            //do more checks, return true or false
        }
        return false //default
    }
}

1 Ответ

0 голосов
/ 26 августа 2018
public class FakeFeatureManagerForTesting: FeatureManager {
  public var userEnabledFeature = false //is this legal? Why is compiler not complaining?
}

В протоколе говорится, что соответствующие ему члены должны иметь свойство Bool userEnabledFeature, которое может быть прочитано, а не свойство только для чтения.Однако, если у вас есть переменная с типом протокола, это не позволит вам присвоить свойство, даже если значение переменной является реализацией, если оно доступно для записи.

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

Вы можете получить вычисляемое свойство следующим образом:

public class FakeFeatureManagerForTesting: FeatureManager {
  public var userEnabledFeature: Bool { 
    // do some work here and return value or fallback to false
    return false
  }
}

С другой стороны, вы также можете иметь только частное настраиваемое свойство, которое можно изменить только из файла или класса / структуры:

public class FakeFeatureManagerForTesting: FeatureManager {
  public private(set) var userEnabledFeature = false

  public func updateUserEnabledFeature(enabled: Bool) {
    userEnabledFeature = enabled // will work just fine
  }
}

let manager = FakeFeatureManagerForTesting()
manager.updateUserEnabledFeature(enabled: true) // will work
manager.userEnabledFeature = true // won't compile, because modifying is allowed privately only
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...