Swift: Selector Syntax Sugar
Objective-C developers be jelly
Objective-C has been around for several years, and during that time developers been crafting their code style to make it nice and readable for following generations to benefit. But not Swift, Swift is new. There’s not really a single or most common style to conform with, so a lot of us have had to forge our own way with experimentation.
Over the past 12 months I’ve been fortunate enough to work with Swift for about 98.2% of my working week. During that time I’ve learnt to craft some (in my opinion) really nice code styles, which I’ll share part of with you today.
Selectors
Before Swift 2.2, selectors were string literals and prone to error because we, as humans invented, and still contribute to typos whenever given the chance to write something without autocomplete.
A few other examples of how I like to name corresponding user interaction functions:
Improvements in Swift 2.2
However, our selectors are now much safer in Swift 2.2, but it’s still
U-G-L-Y (It ain’t got no alibi). And to have all these selectors littered throughout your codebase makes the matter worse. What if you have Massive View Controller? What if you use the same selector multiple times?
This line is seriously way too long and kind of hard to read if you’re just scanning through. Imagine writing/copy-pasting that several times. Let’s tidy it up by placing all the selectors in one spot, where we can reference and edit them in a uniform matter.
Awesome. Now we have one spot to put all our selectors in, and each object that wants to use that selector, gets it’s value from a static constant inside the Action struct. We have to use the name Action because it’s the next best thing to Selector, because Selector is taken by the Selector class (obviously).
Another wise thing to do is to use the same names for the static constant and functions, this will help you remember and maintain uniformity.
I had actually been using this for quite a few months now, and it has served me well for that time. But this morning I realised I could take this even further, and make it more … sugary. Why make an Action struct when we can make a Selector extension?
Omg, right? We’ve made an extension to Selector which contains a static constant of the selector we want to use to call the method in our class.
It’s just like when you omit UIColor namespace for setting a color to a view:
Sample code of this post can be found on GitHub.
@selector() в Swift?
Я пытаюсь создать NSTimer на Swift но у меня возникли некоторые проблемы.
test() является функцией в том же классе.
Я получаю сообщение об ошибке в Редакторе:
не удалось найти перегрузку для «init», которая принимает поставляемое доводы
когда я меняю selector: test() до selector: nil ошибка исчезает.
но ничего не работает и я не могу найти решение в ссылках.
21 ответов
но есть еще ряд важных API на основе ObjC, которые используют селекторы, включая таймеры и шаблон цели/действия. Быстрый обеспечивает Selector тип для работы с этими. (Swift автоматически использует это вместо ObjC SEL тип.)
в Swift 2.2 (Xcode 7.3) и более поздних версиях (включая Swift 3 / Xcode 8 и Swift 4 / Xcode 9):
вы можете построить Selector из типа функции Swift с помощью #selector выражение.
самое замечательное в этом подходе? Ссылка на функцию проверяется компилятором Swift, поэтому вы можете использовать #selector выражение только с парами классов / методов, которые фактически существуют и могут использоваться в качестве селекторов (см. «доступность селектора» ниже). Вы также можете сделать свою ссылку на функцию только такой конкретной, как вам нужно, в соответствии с правила Swift 2.2+ для именования типов функций.
есть несколько дополнительных предостережений для ссылок на функции, которые вы передаете в #selector выражение:
Общие сведения:
вы можете узнать больше о селекторах в разделе взаимодействие с Objective-C APIs на использование Swift с какао и Objective-C.
вот краткий пример того, как использовать Selector класс на Swift:
обратите внимание, что если метод, переданный как строка, не работает, он завершится ошибкой во время выполнения, а не во время компиляции и приведет к сбою приложения. Будьте осторожны!—3—>
кроме того, если ваш (Swift) класс не происходит от класса Objective-C, то вы должны иметь двоеточие в конце строки имени целевого метода, и вы должны использовать свойство @objc с вашим целевым методом, например
в противном случае вы получите ошибку «нераспознанный селектор» во время выполнения.
для будущих читателей я обнаружил, что у меня возникла проблема и я получал unrecognised selector sent to instance ошибка, вызванная пометкой цели func как частная.
на func должны быть публично видимым для вызова объектом со ссылкой на селектор.
Swift 2.2+ и Swift 3 Обновление
использовать новый #selector выражение, которое устраняет необходимость использования строковых литералов, что делает использование менее подверженным ошибкам. Для справки:
Примечание (Swift 4.0):
при использовании #selector вам нужно будет отметить функцию как @objc
@objc func something(_ sender: UIButton)
на случай, если у кого-то еще есть та же проблема, что и у меня с NSTimer, где ни один из других ответов не исправил проблему, действительно важно упомянуть, что, если вы используете класс, который не наследуется от NSObject напрямую или глубоко в иерархии(например, вручную созданные swift-файлы), ни один из других ответов не будет работать, даже если указано следующее:
Не изменяя ничего, кроме как просто наследования класса от NSObject я остановился получение ошибки «непризнанный селектор» и получил мою логику, как ожидалось.
Swift 4.0
создать селектор, как показано ниже.
1.добавьте событие в кнопку, например:
и функция будет как ниже:
Если вы хотите передать параметр функции из NSTimer, то вот ваше решение:
включите двоеточие в текст селектора (tester:), и ваши параметры перейдут в userInfo.
ваша функция должна принимать NSTimer в качестве параметра. Затем просто извлеките userInfo, чтобы получить переданный параметр.
селекторы являются внутренним представлением имени метода в Objective-C. В Objective-C «@selector(methodName)» преобразует метод исходного кода в тип данных SEL. Поскольку вы не можете использовать синтаксис @selector в Swift (там находится rickster), вам нужно вручную указать имя метода как строковый объект напрямую или передать строковый объект типу селектора. Вот пример:
Swift 4.1
С образцом жеста крана
дополнительные сведения см. В документе Apple:Выражение Селектора
@selector() in Swift?
I’m trying to create an NSTimer in Swift but I’m having some trouble.
test() is a function in the same class.
I get an error in the editor:
Could not find an overload for ‘init’ that accepts the supplied arguments
When I change selector: test() to selector: nil the error disappears.
But nothing works and I can’t find a solution in the references.
23 Answers 23
But there are still a number of important ObjC-based APIs that use selectors, including timers and the target/action pattern. Swift provides the Selector type for working with these. (Swift automatically uses this in place of ObjC’s SEL type.)
In Swift 2.2 (Xcode 7.3) and later (including Swift 3 / Xcode 8 and Swift 4 / Xcode 9):
You can construct a Selector from a Swift function type using the #selector expression.
The great thing about this approach? A function reference is checked by the Swift compiler, so you can use the #selector expression only with class/method pairs that actually exist and are eligible for use as selectors (see «Selector availability» below). You’re also free to make your function reference only as specific as you need, as per the Swift 2.2+ rules for function-type naming.
There are a couple of extra caveats for the function references you pass to the #selector expression:
General notes:
Cases where #selector doesn’t work, and naming: Sometimes you don’t have a function reference to make a selector with (for example, with methods dynamically registered in the ObjC runtime). In that case, you can construct a Selector from a string: e.g. Selector(«dynamicMethod:») — though you lose the compiler’s validity checking. When you do that, you need to follow ObjC naming rules, including colons ( : ) for each parameter.
Selector availability: The method referenced by the selector must be exposed to the ObjC runtime. In Swift 4, every method exposed to ObjC must have its declaration prefaced with the @objc attribute. (In previous versions you got that attribute for free in some cases, but now you have to explicitly declare it.)
Remember that private symbols aren’t exposed to the runtime, too — your method needs to have at least internal visibility.
You can read more about selectors under Interacting with Objective-C APIs in Using Swift with Cocoa and Objective-C.
Что нового в Swift 3?
Как мы все давно знаем, Apple интегрировала Swift 3 в Xcode 8. Это первая версия языка с открытым исходным кодом, который работает как на macOS, так и на Linux. Если вы следили за процессом развития языка на Swift Evolution с декабря прошлого года и успели с ним поэкспериментировать в IBM sandbox, вы уже наверное поняли, что в нем появилось множество изменений. Совершенно уверен, что при компилировании существующего проекта в Xcode 8, ваш код удивит вас наличием ошибок. Но это поправимо. Давайте познакомимся с некоторыми изменениями в новой версий языка.
Изменения в новой версий, можно разделить две основные категории:
Операторы инкремента и декремента наследия языка C и их функциональность проста — добавить один или вычесть один к определенной переменной:
Тем не менее, все становится сложнее, когда дело доходит до принятия решения, какой из них выбрать. Каждый из них может быть представлен в двух возможных вариантах: префикс и постфикс — они все функционируют благодаря движку и возвращают значения, которые вы можете использовать или отклонить благодаря перезаггрузке операторов.
Это больше чем достаточно для начинающих, так как они были удалены — используйте операторы присваивания и сложение += и вычитание -= вместо:
Конечно, вы можете использовать операторы сложения (+) и вычитания (-), а также — совместно использовать операторы присваивания, благодаря чему вы сможете экономить свое время при написании кода, хотя:
Для ознакомления: Если вы хотите больше узнать о мотивах этого изменения, посмотрите предложение Криса Латнера по этому поводу.
Стиль языка С для написания циклов уже история
Наиболее распространенным примером использования операторов инкрементов и декрементов является стиль языка С для написания цикла. Удаление операторов означает удаление всего что с ними связано, поскольку с этим всем вы уже ничего не сможете сделать, в отличии от того, что вы делали ранее с выражениями и оператором для указания диапазона.
Например, если у вас есть несколько знании, вы вероятно будете использовать цикл for для отображения числа от 1 до 10:
В Swift 3 это невозможно. Это его прототип в языке Swift 3 — давайте рассмотрим оператор закрытого диапазона (. ) в действии:
В качестве альтернативы, вы можете также использовать для-каждого цикла с замкнутыми выражениями и сокращёнными аргументами — боле подробную информацию вы можете найти здесь.
Для ознакомления: Если вы хотите узнать больше о мотивации этого изменения, посмотрите предложение Эрики Садун.
Удалили переменную из параметров функции
Параметры функции обычно определяются как константы, поскольку их не нужно изменять внутри функций. Тем не менее, существуют определенные случаи, когда объявление их как переменные может пригодиться. В Swift 2, вы можете отметить параметр функции как переменную с ключевым словом var. После того, как параметр будет указан как var, он создаст локальную копию значения, поэтому вы сможете изменять ее значение в теле функции.
В качестве примера, следующая функция определяет наибольший общий делитель двух заданных чисел — если вы упустили математический курс в средней школе, почитайте больше об этом здесь:
Алгоритм прост: если оба числа уже равны, выполняется возврат одного из них. В противном случае, сравните их, выполните вычитание меньшего из большего и присваивайте результат к большему, пока они не станут равными и выполните возвращение любого из них. Как вы видите, пометив а и Ь в качестве переменных, мы можем изменить их значения в функции.
Swift 3 больше не позволяет разработчикам устанавливать параметры функции, как переменные, поскольку разработчики Swift могут запутаться между var и inout. Таким образом, последняя версия Swift просто удаляет var из параметров функции.
Поэтому, чтобы написать ту же самую функцию gcd в Swift 3, необходим иной подход. Вам нужно сохранить значения параметров функции для локальных переменных:
Если вы хотите узнать больше о мотивах этого решения, вы можете прочитать оригинальное предложение.
Последовательное поведение лейблы для параметров функции
Списки параметров функции являются кортежи, так что вы можете использовать их для вызова функций, до тех пор, пока структура кортежа совпадает с прототипом функции. Возьмем функцию gcd() в качестве примера. Вы можете выполнить вызов следующим образом:
Или вы можете даже вызвать функцию, как показано ниже:
Как вы видите в Swift 2, вам не нужно указать метку первого параметра. Тем не менее, вы должны указать метку для второго (и остальных параметров) при вызове функции.
Этот синтаксис является запутанным для начинающих разработчиков, поэтому он предназначен для стандартизации поведения меток. В новой версий языка Swift, вы можете вызвать функцию следующим образом:
Вы должны явно указать метку для первого параметра. Если вы не сделаете этого, Xcode 8 покажет вам сообщение об ошибке.
Ваша первая реакция на это изменение может выглядеть подобно «OMG! Мне придется сделать много изменений в существующем коде ». Вы правы. Это тонны изменений. Таким образом, компания Apple предлагает способ подавить первую метку параметра вызова функции. Вы можете добавить подчеркивание к первому параметру, как показано ниже:
Делая это, вы можете вызвать функцию, используя старый способ — без указания первой метки. Это поможет сделать миграцию кода с Swift 2 на Swift 3 намного проще.
О мотивации и намерении этого изменения, вы можете прочесть это предложение.
Селекторы как строки больше не используются
Давайте создадим кнопку и выполним какое-то действие, при нажатии на нее — используйте только playground, а не storyboard:
Там происходит довольно много событий, так что давайте разобьем их на этапы:
Чтобы устранить потенциальную проблему во время компиляции, в Swift 3 заменили строку селекторов ключевым словом #selector(). Это позволяет компилятору обнаружить проблему раньше, если вы не правильно укажите имя метода.
Для понимания причин этого изменения, вы можете прочесть предложение Доуга Грегора.
Это что касается удаленных функций. Теперь давайте перейдем к основным моментам модернизации языка.
Key-paths в виде строки
Эта функция аналогична предыдущей, но она относится key value coding (KVC) и ключевому-значению наблюдения (KVO):
Вы создаете класс Person, который соответствует ключевому-значению кодирования, создаете мою идентичность с классом назначенным инициализатором и используете KVC, чтобы установить имя.
Опять же, если вы сделаете это неправильно, все взорвется!
К счастью, это больше не произойдет в Swift 3. Key-path, были заменены выражением #keyPath():
Для понимания причин данного изменения, вы можете прочесть предложение Девида Хартс.
Удален префикс базовых типов NS
Убрали префикс NS для базовых типов. Посмотрим как это работает. Типичным примером является работа с JSON:
Для этой процедуры изменения присвоения имен, вы можете проверить это предложение, написанное Тони Паркером и Филиппом Хауслером.
Давайте вычислим окружности и площадь круга с заданным радиусом:
Для старых версий Swift, вы используете M_PI для обозначения константы pi. Swift 3 интегрирует константу pi в тип Float, Double и CGFloat:
Выше представленный фрагмент кода будет написан, как это в Swift 3:
С помощью логического вывода типа, вы можете даже опустить тип. Вот короткая версия:
Grand Central Dispatch
Grand Central Dispatch используется для сетевых операций, которые не блокируют пользовательский интерфейс в основном потоке. Он написано на языке C и его API является большой сложностью для начинающих разработчиков, даже для выполнения простых задач, таких как создание асинхронной очереди и выполнения каких-либо операций:
Swift 3 устраняет весь шаблонный код и избыточный материал, принимая объектно-ориентированный подход:
Для получения дополнительной информации об этом изменении, вы можете прочитать написанное Мэттом Райт.
Core Graphics теперь больше Swifty
Core Graphics представляет собой мощный графический фреймворк, но он использует интерфейс в стиле С, похожий на GCD:
Вы создаете view frame, расширяя класс UIView, переопределив метод DrawRect ().
Swift 3 принимает совершенно иной подход — сначала разворачивает текущий графический контекст и выполняет все операции рисования, впоследствии связанные с ним:
Примечание: Контекст будет нулевым перед вызовом метода DrawRect(), поэтому вам необходимо его развернуть при помощи выражения guard — подробнее об этом здесь.
Соглашение о присвоении имен глаголов и существительных
Время для грамматики! Группы методов в Swift 3 делятся на две категории: методы, которые возвращают некоторое значение — подразумеваются как существительные — и методы, которые выполняют определенный вид действий — подразумеваются как глаголы.
Здесь выполняется вывод от 10 до 1:
Вы используете метод reverse(), для изменения диапазона. Swift 3 обрабатывает эту операцию как существительное, так как он возвращает исходный диапазон в обратном порядке. Он добавляет суффикс “ed” к методу:
Наиболее распространенное использование кортежей/tuples, чтобы вывести содержимое массива:
Swift 3 обрабатывает этот метод как существительное, так как он возвращает кортеж, содержащий текущий индекс и значение этого массива, и добавляет суффикс “ed” к нему:
Другим примером может служить сортировка массива. Вот пример того, как вы можете отсортировать массив в порядке возрастания:
Swift 3 обрабатывает эту операцию как существительное, так как он возвращает отсортированный массив. Метод sort теперь называется sorted:
Давайте отсортируем массив, без использования промежуточной константы. В Swift 2, вы можете вызвать функцию следующим образом:
Вы используете sortInPlace() для сортировки изменяемого массива. Swift 3 обрабатывает этот метод как глагол, так как он выполняет фактическую сортировку без возвращения значений. Он использует только базовое слово, которое описывает действие. Так sortInPlace() теперь называется sort():
Более подробную информацию о соглашении об именах, вы можете проверить в API Design Guidelines.
API в языке Swift
Swift 3 принимает простую философию для своих API, — опустить ненужные слова, так что если что-то является излишним или может быть выведено из контекста, удалите его:
Swift 3 обрабатывает перечисление как свойства, так что используйте lowerCamelCase вместо upperCamelCase для них:
@discardableResult
В Swift 3, Xcode покажет вам предупреждение, если вы не используете возвращаемое значение функции или метода. Вот пример:
В приведенном выше коде, метод printMessage возвращает полученное сообщение для вызывающего объекта. Тем не менее, возвращаемое значение не используется. Это может быть потенциальной проблемой, так что компилятор в Swift 3 даст вам предупреждение.
В данном случае, если это не является обрабатываемым возвращаемым значением. Вы можете подавить предупреждение путем добавления @discardableResult в объявлении метода:
Документация


Выражения
В Swift существуют четыре вида выражений: префиксные, бинарные, первичные и постфиксные выражения. При оценке выражения происходит возврат значения, вызывается побочный эффект, или и то и другое.
Префиксные и бинарные выражения позволяют применять операторы к небольшим выражениям. Первичные выражения концептуально являются самым простым видом выражений и обеспечивают способ доступа к значениям. Постфиксные выражения, также как префиксные и бинарные выражения, позволяют создавать более сложные выражения с использованием постфиксов: такие как вызов функций и доступ к членам. Каждый вид выражений подробно описан в разделах ниже.
Грамматика выражений
Префиксные выражения
Получить информацию об операторах, предоставляемых стандартной библиотекой Swift, см. Operator Declarations.
В дополнение к стандартным библиотечным операторам, можно использовать & непосредственно перед именем переменной, которая передается как in-out аргумент выражению вызова функции. Для получения дополнительной информации см. Сквозные параметры.
Грамматика префиксных выражений
Оператор Try
Если выражение генерирует ошибку, выходит ошибка выполнения.
Выражение try не может появиться справа бинарного оператора до той поры, пока бинарный оператор не является оператором присваивания или выражение try не заключено в скобки.
Грамматика выражения try
Бинарные выражения
Бинарные выражения объединяют инфиксный бинарный оператор и выражение, которое принимает левосторонние и правосторонние аргументы. Вот так оно выглядит:
Подробнее о операторах, представленных в стандартной библиотеке Swift читайте в Operator Declarations.
Заметка
Грамматика бинарных выражений
Оператор присваивания
Оператор присваивания устанавливает новое значение для данного выражения. Выглядит он вот так:
Значение выражения устанавливается равным значению, полученному путем оценки значения. Если выражение является кортежем, то значение должно быть кортежем с таким же количеством элементов. (Вложенные кортежи допускаются.) Присваивание осуществляется из каждой части значения к соответствующей части выражения. Например:
Оператор присваивания не возвращает никакого значения.
Грамматика оператора присваивания
Тернарный условный оператор
Тернарный условный оператор принимает значение одного из двух заданных значений в зависимости от условия. Выглядит это так:
Если условие true, условный оператор вычисляет первое выражение и возвращает его значение. В противном случае, он вычисляет второе выражение и возвращает его значение. Неиспользованное выражение не вычисляется.
Грамматика условного оператора
Операторы приведения типа
Выглядят они вот так:
Грамматика операторов приведения типа
Первичные выражения
Первичные выражения являются самым основным видом выражений. Они могут быть использованы в качестве самостоятельных выражений, могут быть объединены с другими токенами для создания префиксных выражений, бинарных выражений, и постфиксных выражений.
Грамматика первичных выражений
Выражения литерала
Литеральное выражение состоит либо из обычного литерала (например, строки или числа), или литерала массива или словаря, или одного из следующих специальных литералов:
При использовании в качестве дефолтного значения функции или метода, значение специального литерала определяется, когда значение дефолтного выражения вычисляется на месте вызова.
Литерал массива представляет собой упорядоченную совокупность значений. Он выглядит следующим образом:
Литерал словаря представляет собой неупорядоченный набор пар ключ-значение. Выглядит он так:
Литерал песочницы используется Xcode для создания интерактивного представления цвета, файла или изображения в редакторе программы. Литералы песочниц в виде обычного текста вне Xcode представлены с использованием специального синтаксиса литерала.
Информацию об использовании литералов песочниц в Xcode см. в разделе Добавление цвета, файла или литерала изображения в справке Xcode.
Грамматика выражения литерала
Выражение Self
В инициализаторе, сабскрипте, или методе экземпляра, self относится к текущему экземпляру типа, в котором находится. В типе метода self относится к текущему типу, в котором находится.
Выражение self используется для определения сферы охвата при доступе пользователей, обеспечивая устранения неоднозначности, когда есть другая переменная с тем же именем в области видимости, например в качестве параметра функции. Например:
Грамматика выражения self
Выражение суперкласса
Выражение суперкласса позволяет классу взаимодействовать с его суперклассом. И имеет одну из следующих форм:
Первая форма используется для доступа к элементу суперкласса. Вторая форма используется для доступа к реализации суперкласса по индексу сабскрипта. Третья форма используется для доступа к инициализатору суперкласса.
Подклассы могут использовать выражение суперкласса в реализации членов, индексации и инициализаторах для того, чтобы с пользой использовать реализацию в их суперклассе.
Грамматика выражения суперкласса
Выражение замыкания
Выражение замыкания создает замыкание. В других языках программирования оно известно как лямбда или анонимная функция. Также как при объявлении функции, замыкание содержит заявления, которые выполняет, и вылавливает константы и переменные из области видимости. Имеет следующий вид:
Параметры имеют ту же форму, что и параметры в объявлении функции, как описано в Функции.
Есть несколько специальных форм, которые позволяют замыканиям быть записанными более кратко:
Следующие выражения замыкания эквивалентны:
Для получения дополнительной информации о передаче замыкания в качестве аргумента функции, см. далее в Выражении вызова функции.
Для получения дополнительной информации о сбегающих замыканиях см. Сбегающие замыкания.
Списки захвата
По умолчанию выражение замыкания захватывает константы и переменные из окружающей его области с сильными ссылками на эти значения. Вы можете использовать списки захвата для того, чтобы явно контролировать то, какие значения захватываются замыканием.
Записи в списке захвата инициализируются при создании замыкания. Для каждой записи в списке захвата, константа инициализируется со значением константы или переменной, которая имеет то же имя в окружающей области. Например, в коде ниже, a включено в список захвата, а b нет, и это приводит к их различному поведению.
Если тип значения выражения является классом, то вы можете отметить выражение в списке захвата как weak или unowned для захвата слабой или бесхозной ссылки на значение выражения.
Кроме того, можно связать произвольное выражение с именованным значением в списке захвата. Выражение вычисляется, когда создается замыкание, а значение захватывается с заданной «силой». Например:
Подробнее о выражениях замыкания см. Замыкания. Подробнее о списках захвата см. Замена циклов сильных ссылок в замыканиях.
Грамматика выражений замыканий
Неявное выражение члена
Неявное выражение члена представляет собой сокращенный способ доступа к члену типа, такому как кейс перечисления или тип метода, в контексте, когда определение типа может определить подразумеваемый тип. Выглядит это так:
Грамматика неявного выражения члена
Выражение в скобках
Выражения в скобках состоят из выражения, окруженного круглыми скобками. Вы можете использовать круглые скобки для явного указания приоритета выполнения той или иной операци. Группировка при помощи скобок никак не меняет типа выражения. Например, тип выражения в скобках (1) является Int.
Грамматика выражения в скобках
Выражение кортежа
Выражение кортежа может иметь 0 выражений или может содержать два или более выражений. Если в скобках находится всего одно выражение, то это уже является выражением в скобках, а не кортежем.
Заметка
Грамматика выражения кортежа
Выражение wildcard
Выражение с подстановочными символами используется для явного игнорирования значения во время присваивания. Например, при следующем присваивании 10 присваивается к x и 20 игнорируется:
Грамматика выражения wildcard
Выражение Key-Path
Path состоит из имени свойств, сабскритов, из выражений опциональных последовательностей, выражений принудительного извлечения.
Каждый из компонентов key-path может быть повторен столько раз, сколько нужно в любой последовательности.
Имя типа может быть пропущено в контексте, где тип может быть определен. Следующий код использует \.someProperty вместо \SomeClass.someProperty :
Путь может ссылаться на self для индентификации пути ключа через ( \.self ). Путь до ключа ссылается на сам экземпляр, так что вы можете использовать его для того, чтобы изменить все данные, хранящиеся в переменной всего за один шаг. Например:
Для более подробной информации по использованию key-path в коде, который взаимодействует с Objective-C APIs, смотрите Using Objective-C Runtime Features in Swift. Для более подробной информацией по KVC и KVO смотрите Key-Value Coding Programming Guide и Key-Value Observing Programming Guide.
Грамматика выражения Key-Path
Выражение селектора
Выражение селектора позволяет получить доступ к селектору, используемому для обозначения метода или геттера или сеттера свойства в Objective-C.
Когда создаем селектор для геттера свойства, имя свойства может быть ссылкой на переменную или константу свойства. И наоборот, когда создаем селектор для сеттера свойства, имя свойства должно быть ссылкой на переменное свойство.
Имя метода может содержать скобки для группировки, также как оператор as содержит их для устранения неоднозначности между методами, которые разделяют имя, но имеют разные типы сигнатур. Например:
Поскольку селектор создается во время компилляции, а не во время выполнения, компиллятор может проверить существование метода и то, что метод передается Objective-C.
Заметка
Несмотря на то, что имя метода и имя свойства являются выражением, они никогда не вычисляются.
Дополнительные сведения об использовании селекторов в коде на Swift, которые взаимодействуют с API-интерфейсами Objective-C, см. в разделе Особенности исполнения Objective-C в Swift.
Грамматика выражения селектора
Выражение значения пути по ключу
Выражения пути по ключу позволяют вам получить доступ к строке, которая относится к свойству в Objective-C для использования в KVC и в KVO API’s.
Имя свойства должно ссылаться на свойство, которое доступно во время исполнения в Objective-C. Во время компилляции выражение пути отображается в виде строкового литерала. Например:
Когда вы используете выражение строки ключевого пути внутри класса, вы можете ссылаться на свойство этого класса, написав просто имя свойства без имени класса.
Так как путь создается во время компилляции, а не во время исполнения, компиллятор может проверить, что свойство существует и открыто для Objective-C исполнения.
Дополнительные сведения об использовании ключевых путей в коде Swift, которые взаимодействуют с API-интерфейсами Objective-C, см. В разделе Использование функций времени выполнения Objective-C в Swift. Информацию о кодировании значения ключа и наблюдении за ключевыми значениями см. В Руководстве по программированию кода ключа и Руководстве по программированию по ключевым значениям.
Заметка
Несмотря на то, что имя свойства является выражением, оно никогда не вычисляется.
Грамматика выражения значения пути по ключу
Постфиксные выражения
Для получения информации о поведении этих операторов см. Базовые операторы и Продвинутые операторы.
Для получения информации о предоставляемых стандартной библиотекой Swift операторах см. Operator Declarations.
Грамматика постфиксных выражений
Выражение вызова функции
Выражение вызова функции состоит из имени функции, за которой следует разделенный запятыми список аргументов функции в скобках. Вызов функции выражения имеют следующий вид:
Именем функции может быть любое выражение, значение которого имеет функциональный тип.
Если определение функции включает в себя имена параметров, то написание вызова функции должно первоначально включать в себя имена, а затем и значения аргументов, разделенных двоеточием ( : ). Выглядит это вот так:
Выражение вызова функции может включать последующее замыкание в виде выражения замыкания сразу после закрывающей скобки. Последующее замыкание понимается как аргумент функции, добавленное после последнего аргумента в скобках. Следующие вызовы функций эквивалентны:
Если последующее замыкание является единственным аргументом функции, круглые скобки могут быть опущены.
Грамматика выражения вызова функции
Выражение инициализатора
Выражение инициализатора обеспечивает доступ к инициализатору типа. Имеет следующий вид:
Вы используете выражение инициализатора в выражение вызова функции для инициализации нового экземпляра типа. Вы также использовуете выражение инициализатора для делегирования инициализатору суперкласса.
Как и функции, инициализатор может быть использован в качестве значения. Например:
Если вы указываете тип по имени, то вы можете получить доступ к инициализатору типа без использования самого выражения инициализатора. Во всех остальных случаях необходимо использовать выражение инициализатора.
Грамматика выражения инициализатора
Явное выражение члена
Члены именованного типа названы как часть объявления типа или расширения. Например:
Члены кортежа неявно названы интеджерами в порядке их появления, начиная с нуля. Например:
Члены модуля получают доступ к объявлению топ-уровня этого модуля.
Для того, чтобы различать методы или инициализаторы, чьи имена отличаются только именами своих аргументов, возьмите имена аргументов в скобки, и после каждого имени аргумента поставьте двоеточие ( : ). Поставьте подчеркивание ( _ ) для аргумента без имени. Для того, чтобы различать перегруженные методы, используйте аннотацию типа. Например:
Если период появляется в начале строки, он понимается как часть явного выражения членов, а не как неявное выражение члена. Например, в следующем примере показаны последовательные вызовы методов, приведшие к разбиению на несколько строк:
Грамматика явного выражения члена
Постфиксное выражение Self
Грамматика выражения self
Выражение сабскрипта
Выражение сабскрипта обеспечивает доступ к индексу с помощью геттера и сеттера, соответствующего сабскрипту объявления. Выглядит следующим образом:
Для того, чтобы определить значение выражения сабскрипта, сабскрипт геттера для типа выражения вызывается с выражениями индекса, передаваемых в качестве параметров индекса. Для того, чтобы установить его значение, сабскрипт сеттера вызывается таким же образом.
Информацию об объявлениях подстрочных индексов см. в Объявление протокола сабскрипта.
Грамматика выражения сабскрита
Выражения принудительного значения
Развернутое значение выражения принудительного значения может быть изменено, либо через изменение самого значения, или путем его присвоения одному из членов-значения. Например:
Грамматика принудительного значения
Выражение опциональной цепочки
Выражение опциональной цепочки служит для упрощенного синтаксиса и использования опциональных значений в постфиксных выражениях. Выглядит вот так:
В следующем варианте показано поведение примера выше без использования опциональной цепочки.
Грамматика выражения опциональной последовательности
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.






