Во-первых, позвольте мне поговорить о property. Предположим, что если нам нужно изменить или получить доступ к iVar в вашем классе, используя объект вашего класса, тогда должны быть методы getter и setter, назначенные iVar. Свойство используется в основном, когда другим объектам необходимо изменить или получить доступ к ivars в вашем объекте, без ручного определения методов получения и установки или использования @property (в объекте - c).

В objective-c @property объявляет свойство в заголовке вашего класса. Вот пример:

@property (nonatomic, retain) NSString *myString;

@synthesize создает ваши сеттеры и получатели для вашего свойства (методы доступа). Без synthesize вы должны написать свою собственную реализацию setter и getter, например getMyString или setMyString (используйте первый символ вашего свойства с заглавной буквы).

Итак, указанное выше объявление свойства эквивалентно:

- (NSString*)myString {}
- (void)setMyString:(NSString*)newValue {}

Свойства можно разделить на Сохраненные свойства и Вычисляемые свойства.

Сохраненное свойство и вычисляемое свойство

Сохраненные свойства хранят значения констант и переменных как часть экземпляра, тогда как вычисляемые свойства вычисляют (а не сохраняют) значение.

►Вычисляемые свойства предоставляются классами, структурами и перечислениями.

►Сохраняемые свойства предоставляются только классами и структурами.

В простейшей форме хранимое свойство - это константа или переменная, которая хранится как часть экземпляра определенного класса или структуры. Сохраненные свойства могут быть либо сохраняемыми свойствами переменных (вводятся varkeyword), либо постоянными хранимыми свойствами (вводятся ключевым словом let).

В приведенном ниже примере определяется структура с именем FixedLengthRange, которая описывает диапазон целых чисел, длина диапазона которых не может быть изменена после его создания:

struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the range now represents integer values 6, 7, and 8

Экземпляры FixedLengthRange имеют свойство хранения переменной, называемое firstValue, и постоянное свойство хранения, называемое length. В приведенном выше примере length инициализируется при создании нового диапазона и не может быть изменен после этого, потому что это постоянное свойство.

Сохраненные свойства экземпляров постоянной структуры

Если вы создаете экземпляр структуры и назначаете этот экземпляр константе, вы не можете изменять свойства экземпляра, даже если они были объявлены как свойства переменных:

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// this will report an error, even though firstValue is a variable property

Поскольку rangeOfFourItems объявлен как константа (с ключевым словом let), невозможно изменить его свойство firstValue, даже если firstValue является свойством переменной.

ПРИМЕЧАНИЕ. Такое поведение вызвано тем, что структуры являются типами значений. Когда экземпляр типа значения помечен как константа, все его свойства помечены как константа.

То же самое не относится к классам, которые являются ссылочными типами. Если вы назначаете экземпляр ссылочного типа константе, вы все равно можете изменить свойства переменной этого экземпляра.

Ленивые сохраненные свойства

отложенное сохраненное свойство - это свойство, начальное значение которого не вычисляется до первого использования. Вы указываете ленивое сохраненное свойство, записывая модификатор lazy перед его объявлением.

См. Мою статью о lazy var: lazy var в ios swift

Вычисленные свойства

В дополнение к сохраненным свойствам классы, структуры и перечисления могут определять вычисляемые свойства, которые на самом деле не хранят значения. Вместо этого они предоставляют геттер и дополнительный сеттер для косвенного извлечения и установки других свойств и значений.

Если вы определяете get { } внутри объявления свойства, это свойство превращается в вычисляемое свойство. И у него не может быть начального значения, так как при доступе к свойству он всегда будет вызывать функцию get{}, объявленную в свойстве.

Мы можем пропустить связанные ключевые слова get и set и их фигурные скобки, если нам не нужно устанавливать значение переменной. Вычисляемое свойство с получателем, но без сеттера, известно как вычисляемое свойство только для чтения. Посмотрите на пример ниже:

var a:String{
return “a”
}
print(a) // prints a

Вышеприведенное объявление такое же, как:

var a:String{
get {
return “a”
}
}

►Мы можем использовать необязательный установщик для вычисляемой переменной, который принимает новое значение в качестве параметра.

class Alphabets {
var _a:String?
var a:String {
get {
return _a ?? “not set”
}
set(newVal) { //you can use any name for the passed parameter.Default is newValue
_a = newVal
}
}
}
/*----------------------------------------------------*/
let alphabet1 = Alphabets()
alphabet1.a = “a”
print(alphabet1.a) // prints a

Если установщик вычисляемого свойства не определяет имя для нового значения, которое должно быть установлено, используется имя по умолчанию newValue. Вот альтернативная версия класса Alphabets, в которой используется это сокращенное обозначение:

class Alphabets {
var _a:String?
var a:String {
get {
return _a ?? “not set”
}
set { // no values passed..
_a = newValue // default value name is newValue
}
}
}
/* — — — — — — — — — — — — — — — — — */
let alphabet1 = Alphabets()
alphabet1.a = “a”
print(alphabet1.a) // prints a

Что произойдет, если вы попытаетесь установить вычисляемое свойство в его собственном сеттере?

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

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

Наблюдатели за недвижимостью:

Наблюдатели за недвижимостью наблюдают и реагируют на изменения стоимости собственности. Наблюдатели свойств вызываются каждый раз, когда устанавливается значение свойства, даже если новое значение совпадает с текущим значением свойства. Вы можете добавить наблюдателей свойств к любым сохраненным свойствам, которые вы определяете, за исключением ленивых сохраненных свойств. Мы можем добавить наблюдателей за свойством к «унаследованному» свойству методом «переопределения».

У вас есть возможность определить одного или обоих этих наблюдателей на свойстве:

  • willSet вызывается непосредственно перед сохранением значения.
  • didSet вызывается сразу после сохранения нового значения.

Если вы реализуете willSet наблюдателя, он передает новое значение свойства как постоянный параметр. Вы можете указать имя для этого параметра как часть вашей willSet реализации. Если вы не укажете имя параметра и круглые скобки в своей реализации, параметр станет доступным с именем параметра по умолчанию newValue.

Точно так же, если вы реализуете didSet наблюдателя, ему передается постоянный параметр, содержащий старое значение свойства. Вы можете назвать параметр или использовать имя параметра по умолчанию oldValue.

Вот пример, приведенный Apple для объяснения потока:

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

Примечание. Вычисляемое свойство должно быть переменной.

let b:Int {
return 4 //error. error: ‘let’ declarations cannot be computed properties
}

Свойства типа:

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

Вы также можете определить свойства, которые принадлежат самому типу, а не какому-либо одному экземпляру этого типа. Всегда будет только одна копия этих свойств, независимо от того, сколько экземпляров этого типа вы создадите. Такие свойства называются свойствами типа.

В Swift свойства типа записываются как часть определения типа внутри фигурных скобок типа, и каждое свойство типа явно привязано к типу, который он поддерживает.

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

static и class оба связывают метод с классом, а не с экземпляром класса. Разница в том, что подклассы могут переопределять class методы; они не могут переопределить static методы.

В приведенном ниже примере показан синтаксис для свойств типа:

В приведенном выше примере мы пытались переопределить статическую функцию в подклассе Enemy, но получили ошибку типа: error: cannot override static method.

Если вам понравилось читать этот пост и вы нашли его полезным, поделитесь им и порекомендуйте его, чтобы другие могли его найти 💚💚💚💚💚💚 !!!!

Спасибо!!