2016-08-31 2 views
8

Я изучал причины, по которым мы должны использовать Get и Set для наших свойств.Getters and Setters in Swift - Имеет ли смысл использовать WillSet и DidSet вместо этого?

Я заметил 3 основные причины, по которым он

  1. Если вы хотите сделать/проверить что-то перед вами на самом деле установить свойство
  2. Если вы хотите, чтобы иметь свойство, которое вы можете получить только от это (возможно, в целях безопасности, я предполагаю?), или дать ему различный доступ уровней.
  3. Скрытие внутреннего представления свойства при экспонировании объекта с использованием альтернативного представления. (Что для меня не сделать много смысла, так как я могу получить доступ к нему на неправильном месте, используя функцию Set в любом случае)

Приведенный ниже код является примером того, как вы бы реализовать и получить набор для недвижимость в Swift, воспользовавшись этими 3 пункта я упомянул:

class Test 
{ 
    private var _testSet:String! 
    private var _testGetOnly:String 
    var testSet:String{ 
     get{ 
      return _testSet 
     } 
     set{ 
      _testSet = newValue + "you forgot this string" 
     } 
    } 
    var testGetOnly:String!{ 
     get{ 
      return _testGetOnly 
     } 
    } 

    init(testSet:String, testGetOnly:String) 
    { 
     _testSet = testSet 
     _testGetOnly = testGetOnly 
    } 
} 

но это другой пример ниже, также воспользоваться этими точками упомянутых, но вместо того, чтобы использовать другое вычисляемое свойство возвращать значение частной собственности, я просто использовать willSet и didSet наблюдатели

class Test 
{ 
    var testGet:String { 
     willSet{ 
      fatalError("Operation not allowed") 
     } 
    } 
    var testWillSet:String!{ 
     didSet{ 
      self.testWillSet = self.testWillSet + "you forgot this string" 
     } 
    } 
    init(testGet:String, testWillSet:String) 
    { 
     self.testGet = testGet 
     self.testWillSet = testWillSet 
    } 
} 

Так что мне любопытно узнать, КАКИЕ ПРЕИМУЩЕСТВА И НЕБЛАГОПРИЯТЫ каждой реализации.

Заранее спасибо

+0

Очень интересный вопрос, но я не могу помочь вам с тех пор, как была обнаружена толпа. .. –

+0

willSet и сделалSet - ** наблюдатели **. Они полностью отличаются от геттеров/сеттеров. (Даже не упоминайте, что часто свойства в Swift (например, в расширении протокола) не являются даже свойствами, они являются вычисленными свойствами.) В ответ на ваш вопрос, да, безусловно, эти два наблюдателя являются такими замечательными языковыми функциями , что очень часто вы просто ** не должны беспокоиться об использовании утомительного свойства/шаблона getter/setter больше - отлично. – Fattie

ответ

3

Ваш вопрос сводится к компиляции против ошибки времени выполнения. Для решения ваших 3 вопроса:

  1. Да, willCheck является единственным вариантом здесь
  2. ReadOnly свойства делится на 2 типа: (а) те, чье значение вытекает из других свойств, например, их сумма; и (б) те, которые вы хотите изменить самостоятельно, но не пользователями. У первого типа действительно нет сеттера; второй тип имеет публичный геттер и частный сеттер. Компилятор может помочь вам проверить это, и программа не будет компилироваться. Если вы выбросите fatalError в didSet, вы получите ошибку времени выполнения, и ваше приложение выйдет из строя.
  3. Могут существовать объекты состояния, с которыми вы не хотите, чтобы пользователь свободно взаимодействовал, и да, вы можете полностью скрыть их от пользователей.

Ваш первый пример кода был слишком подробным при определении опорных переменных - вам не нужно это делать. Для иллюстрации этих точек:

class Test 
{ 
    // 1. Validate the new value 
    var mustBeginWithA: String = "A word" { 
     willSet { 
      if !newValue.hasPrefix("A") { 
       fatalError("This property must begin with the letter A") 
      } 
     } 
    } 

    // 2. A readonly property 
    var x: Int = 1 
    var y: Int = 2 
    var total: Int { 
     get { return x + y } 
    } 

    private(set) var greeting: String = "Hello world" 
    func changeGreeting() { 
     self.greeting = "Goodbye world" // Even for private property, you may still 
             // want to set it, just not allowing the user 
             // to do so 
    } 

    // 3. Hide implementation detail 
    private var person = ["firstName": "", "lastName": ""] 
    var firstName: String { 
     get { return person["firstName"]! } 
     set { person["firstName"] = newValue } 
    } 

    var lastName: String { 
     get { return person["lastName"]! } 
     set { person["lastName"] = newValue } 
    } 

    var fullName: String { 
     get { return self.firstName + " " + self.lastName } 
     set { 
      let components = newValue.componentsSeparatedByString(" ") 
      self.firstName = components[0] 
      self.lastName = components[1] 
     } 
    } 
} 

Использование:

let t = Test() 
t.mustBeginWithA = "Bee"  // runtime error 

t.total = 30     // Won't compile 

t.greeting = "Goodbye world" // Won't compile. The compiler does the check for you 
           // instead of a crash at run time 

t.changeGreeting()    // OK, greeting now changed to "Goodbye world" 

t.firstName = "John"   // Users have no idea that they are actually changing 
t.lastName = "Smith"   // a key in the dictionary and there's no way for them 
           // to access that dictionary 

t.fullName = "Bart Simpsons" // You do not want the user to change the full name 
           // without making a corresponding change in the 
           // firstName and lastName. With a custome setter, you 
           // can update both firstName and lastName to maintain 
           // consistency 

Примечание о private в Swift 2 vs. Swift 3: если вы попытаетесь это сделать в Swift 2 игровой площадке, вы найдете t.greeting = "Goodbye world" работы просто хорошо. Это связано с тем, что Swift 2 имеет странный спецификатор уровня доступа: private означает «доступно только в текущем файле».Отделите определение класса и образец кода на разные файлы, и Xcode будет жаловаться. В Swift 3 это было изменено на fileprivate, которое является более четким и сохраняет ключевое слово private для чего-то более похожего на Java и .NET.

 Смежные вопросы

  • Нет связанных вопросов^_^