Материал: iOS сессия ответы

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Неявные возвраты из замыканий с одним выражением

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

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

Здесь тип функции sorted(by:)аргумента метода проясняет, что Boolзначение должно быть возвращено замыканием. Поскольку тело замыкания содержит единственное выражение ( ), которое возвращает значение, двусмысленности нет, и ключевое слово может быть опущено.s1 > s2Boolreturn

Сокращенные имена аргументов

Swift автоматически предоставляет сокращенные имена аргументов встраивать затворы, которые могут быть использованы для обозначения значений аргументов замыкания по именам $0, $1, $2и так далее.

Если вы используете эти сокращенные имена аргументов в своем выражении замыкания, вы можете опустить список аргументов замыкания из его определения, а число и тип сокращенных имен аргументов будут выведены из ожидаемого типа функции. inКлючевое слово также может быть опущена, поскольку выражение укупорочное полностью состоит из его тела:

reversedNames = names.sorted(by: { $0>$1 } )

Здесь $0и $1ссылаются на первый и второй Stringаргументы замыкания .

35 Переменные-замыкания. Метод сортировки массивов.

Создание нового отсортированного массива#

Поскольку Array соответствует SequenceType , мы можем создать новый массив отсортированных элементов, используя встроенный метод сортировки.

2.1 2.2

В Swift 2 это делается с помощью метода sort() .

let sorted = array.sort() // [1, 2, 3]

3.0

С Swift 3 онбылпереименованв sorted() .

let sorted = array.sorted() // [1, 2, 3]

Сортировка существующего массива на месте#

Поскольку Array соответствует MutableCollectionType , мы можем сортировать его элементы на месте.

2.1 2.2

В Swift 2 это выполняется с помощью sortInPlace() .

array.sortInPlace() // [1, 2, 3]

3.0

С Swift 3 онбылпереименованв sort() .

array.sort() // [1, 2, 3]

Примечание. Чтобы использовать вышеуказанные методы, элементы должны соответствовать протоколу Comparable .

Сортировка массива с пользовательским заказом#

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

struct Landmark {

let name : String

let metersTall :Int

}

var landmarks = [Landmark(name: "Empire State Building", metersTall: 443),

Landmark(name: "Eifell Tower", metersTall: 300),

Landmark(name: "The Shard", metersTall: 310)]

2.1 2.2

// sort landmarks by height (ascending)

landmarks.sortInPlace {$0.metersTall < $1.metersTall}

print(landmarks) // [Landmark(name: "Eifell Tower", metersTall: 300), Landmark(name: "The Shard", metersTall: 310), Landmark(name: "Empire State Building", metersTall: 443)]

// create new array of landmarks sorted by name

let alphabeticalLandmarks = landmarks.sort {$0.name < $1.name}

print(alphabeticalLandmarks) // [Landmark(name: "Eifell Tower", metersTall: 300), Landmark(name: "Empire State Building", metersTall: 443), Landmark(name: "The Shard", metersTall: 310)]

3.0

// sort landmarks by height (ascending)

landmarks.sort {$0.metersTall < $1.metersTall}

// create new array of landmarks sorted by name

let alphabeticalLandmarks = landmarks.sorted {$0.name < $1.name}

Примечание. Сравнение строк может дать неожиданные результаты, если строки непоследовательны, см

36.Замыкания - это тип-ссылка.Автозамыкания.

Замыкания - ссылочный тип

Функциональный тип данных — это ссылочный тип (referencetype). Это значит, что замыкания передаются не копированием, а с помощью ссылки на область памяти, где хранится это замыкание.

В примере выше incrementBySeven и incrementByTen константы, но замыкания, на которые ссылаются эти константы имеют возможность увеличивать значение переменных runningTotal, которые они захватили. Это из-за того, что функции и замыкания являются ссылочными типами.

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

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

letalsoIncrementByTen = incrementByTen

alsoIncrementByTen()

//возвращает 50

incrementByTen()

//возвращает 60

Пример выше показывает, что вызов alsoIncrementByTen то же самое, что и вызов incrementByTen. Потому что и та и другая функция ссылаются на одно и то же замыкание: и то, и другое замыкание возвращают один и тот же runningTotal.

Автозамыкания — это замыкания, которые автоматически создаются из переданного выражения. Иными словами, может существовать функция, имеющая один или несколько входных параметров, которые при ее вызове передаются как значения, но во внутренней реализации функции используются как самостоятельные замыкания

Для реализации автозамыкания необходимо следующее: ‰ Входной аргумент должен иметь функциональный тип. В примере, приведенном ранее, аргумент nextName уже имеет функциональный тип ()->String. ‰ Функциональный тип не должен определять типы входных параметров.

37.Выходящие замыкания.

Замыкания – это блоки кода, которые могут быть многократно использованы. Понимание принципа работы замыканий является ключевым аспектом обучения в разработке под iOS.

Выражения замыкания в Swift имеют четкий, ясный, оптимизированный синтаксис в распространенных сценариях. Эти оптимизации включают:

  • Вывод типа параметра и возврат типа значения из контекста

  • Неявные возвращающиеся значения однострочных замыканий

  • Сокращенные имена параметров

  • Синтаксис последующих замыканий

Когда замыкание является последним или единственным параметром функции, вы можете написать код замыкания вне скобок функции. Это называется выходящее замыкание (tralingclosure).

names.sorted{ $0< $1}

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

38.Объектно-ориентированное программирование в Swift. Экземпляры

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

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

Класс является описанием объекта, а объект представляет экземпляр этого класса. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке - наличие двух рук, двух ног, головы, пищеварительной, нервной системы, головного мозга и т.д. Есть некоторый шаблон - этот шаблон можно назвать классом. Реально же существующий человек (фактически экземпляр данного класса) является объектом этого класса.

Для определения класса используется ключевое слово class, после которого идет название класса:

В данном случае класс называется User. Все тело класса заключается в фигурные скобки.

Класс может содержать переменные и константы, которые хранят состояние объекта. Переменные и константы, определенные в классе, еще называют хранимые свойства класса (storedproperties). Например:

Здесь класс User определяет две переменных age и name, которые хранят соответственно возраст и имя пользователя.

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

Кроме переменных и констант в классе могут определены методы. Методы представляют собой функции, ассоциированные с определенным типом - классом, перечислением или структурой:

После определения класса мы можем использовать его в программе, в частности, создавать его объекты:

Чтобы создать объект класса используется инициализатор, который представляет собой следующую конструкцию:

После названия класса идут пустые скобки. Эта конструкция создает объект, ссылку на который хранит переменная tom. Определение переменных и констант класса ничем не отличается от других переменных и констант.

После создания объекта класса мы сможем обращаться к его свойствам и методам. Для обращения к ним используется нотация точки. То есть после названия переменной tom ставится точка, после которой идет название свойства/метода:

Ключевое слово self

Ключевое слово self позволяет обратиться к текущему экземпляру класса:

39.Перечисления. Вложенные перечисления.

Возвращает последовательность пар ( n , x ), где n представляет собой последовательное целое число, начинающееся с нуля, а x представляет собой элемент последовательности.

func enumerated() -> EnumeratedSequence<Array<Element>>

Когда вы перечисляете коллекцию, целая часть каждой пары является счетчиком для перечисления, но не обязательно является индексом парного значения. Эти счетчики могут использоваться в качестве индексов только в экземплярах коллекций с целочисленным индексом, начинающихся с нуля, таких как Array . Для других коллекций счетчики могут быть вне диапазона или неправильного типа для использования в качестве индекса. Чтобы перебрать элементы коллекции с ее индексами, используйте функцию.ContiguousArrayzip(_:_:)

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

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

40-сұрақОператор switchдля перечисления.

Для анализа и разбора значений перечислений можно использовать оператор switch.Рассмотрим пример котором анализируется значение переменной типа AdvancedCurrencyUnit.

switch dollarCurrency {

case .rouble:

print("Рубль") case let .euro(countries, shortname):

print("Евро. Страны: \(countries). Краткоенаименование: \ (shortname)")

case .dollar(let nation, let shortname):

print("Доллар \(nation). Краткое наименование: \(shortname) ") }

Консоль

Доллар usa. Краткое наименование: USD

В операторе switch описан каждый элемент перечисления AdvancedCurrencyUnit, поэтому использовать оператор default не обязательно. Доступ к ассоциированным параметрам реализуется связыванием значений: после ключевого слова case и указания значения в скобках объявляются константы, которым будут присвоены ассоциированные с членом перечисления значения. Так как для всех ассоциированных параметров создаются константы со связываемым значением, оператор let можно ставить сразу после ключевого слова case (это продемонстрировано для члена euro)

41-сұрақ Свойства и методы в перечислениях.

Свойства позволяют хранить в перечислении вспомогательную информацию. Мы уже неоднократно встречались со свойствами в процессе изучения Swift. Свойство в перечислении — это хранилище, аналогичное переменной или константе, объявленное в пределах перечисления и доступное через его экземпляр. В Swift существует определенное ограничение для свойств в перечислениях: в качестве их значений не могут выступать фиксированные значения-литералы, а лишь замыкания. Такие свойства называются вычисляемыми. При каждом обращении к ним происходит вычисление присвоенного замыкания с возвращением получившегося значения.Объявим вычисляемое свойство для разработанного ранее перечисления .За основу возьмем перечисление Smile и создадим вычисляемое перечисление, которое возвращает связанное с текущим членом перечисления значение.

enum Smile:

String { case joy = ":)"

case laugh = ":D"

case sorrow = ":("

case surprise = "o_O"

// вычисляемоесвойство

var description: String {return self.rawValue} }

varmySmile: Smile = .sorrowmySmile.description // ":("

Методы в перечислениях

Методы — это функции внутри перечислений, поэтому их синтаксис и возможности идентичны синтаксису и возможностям изученных ранее функций. Вернемся к примеру с перечислением Smile и создадим метод, который выводит на консоль справочную информацию о предназначении перечисления

enumSmile: String {

casejoy = ":)"

caselaugh = ":D"

casesorrow = ":("

casesurprise = "o_O"

vardescription: String {returnself.rawValue} funcabout(){

print("Перечисление содержит список смайликов ") } }

varotherSmile = Smile.joyotherSmile.about()

Консоль Перечисление содержит список смайликов

42-сұрақ Структуры.Синтаксис объявление структур.Свойства в структурах.

• Структуры объявляются с помощью ключевого слова struct, за которым следует имя создаваемой конструкции. Требования к имени предъявляются точно такие же, как и к имени перечислений: оно должно писаться в верхнем верблюжьем регистре.

• Тело структуры заключается в фигурные скобки и может содержать свойства и методы, подобные тем, что используются в перечислениях, но более функциональные. ПРИМЕЧАНИЕ Объявляя структуру, вы определяете новый тип данных.

СИНТАКСИС

structИмяСтруктуры {

// свойства и методы структуры

}

Объявим структуру, которая будет описывать сущность «игрок в шахматы»

structPlayerInChess {}

varoleg = PlayerInChess() t

ype(of:oleg)

//PlayerInChess.Type

Так как структура PlayerInChess является типом данных, то можно объявить новое хранилище (переменную) данного типа.