Программирование
Что нового в Swift 6.4 после WWDC26
В этой статье рассматриваются наиболее заметные изменения, представленные на WWDC26.
Swift 6.4 включает в себя ряд улучшений языка и дополнений к стандартной библиотеке, которые делают повседневный код более чистым и выразительным. В этой статье рассматриваются наиболее заметные изменения, представленные на WWDC26.
Упрощенная доступность платформы с помощью anyAppleOS
Поскольку Apple унифицировала номера версий ОС на всех платформах, Swift 6.4 делает следующий шаг, позволяя объединить повторяющиеся атрибуты доступности в один токен anyAppleOS.
// Before
@available(macOS 27, iOS 27, watchOS 27, tvOS 27, visionOS 27, *)
func showStatus() { ... }
// After
@available(anyAppleOS 27, *)
func showStatus() { ... }
Когда требуется выделить какую-либо платформу, объедините anyAppleOS со специальным переопределением. Тот же токен работает внутри #if os(anyAppleOS) для условной компиляции.
Управление предупреждениями с помощью @diagnose
Бывают ситуации, когда необходимо вызвать устаревший API при планировании миграции или проверить критически важную функцию на предмет небезопасного использования, не допуская при этом распространения этих проблем на остальную часть проекта. Новый атрибут @diagnose обрабатывает оба случая.
@diagnose(DeprecatedDeclaration, as: ignored, reason: "Migrating incrementally")
func makeApolloMission() -> Mission {
CrewedMission(rocket: makeSaturnIRocket(), ...)
}
Вы можете подавлять, переводить в состояние предупреждения или повышать до ошибки каждое объявление отдельно. Это точный инструмент, а не флаг, действующий в масштабе всего проекта.
Селекторы модулей для разрешения неоднозначности
Когда два импортированных модуля экспортируют одно и то же имя, Swift пытается разрешить конфликт через точечную нотацию. Но этот подход ломается, если в самом модуле есть тип с таким же именем, как у модуля. Новый синтаксис выбора модуля через :: гарантирует, что левая часть всегда будет трактоваться как модуль, а не как тип.
import SwiftUI import Charts let body = SwiftUI::View.self // SwiftUI's View protocol let chart = Charts::View.self // Charts' View type
Селекторы модулей также работают с именами методов. Это полезно, когда тип наследует одноимённые методы из расширений, объявленных в разных модулях.
user.DatabaseKit::delete() // removes from local store user.CloudSync::delete() // removes from remote
Это особенно полезно в сгенерированном коде, например в раскрытиях макросов, где вы не контролируете, что ещё импортировано в проект.
Более удобная работа с Sendable и конкурентностью
В Swift 6.4 исправили несколько небольших неудобств, связанных с конкурентностью. Раньше weak var свойств вынуждало использовать @unchecked Sendable; теперь его можно записать как weak let, и такая запись проходит обычную проверку Sendable без небезопасного выстраивания обходного пути.
final class Spacecraft: Sendable {
weak let dockedAt: SpaceStation?
}
Когда класс должен явно отказаться от соответствия Sendable, это можно указать с помощью ~Sendable, вместо того чтобы оставлять это поведение неявным.
class Mission: ~Sendable { ... }
class CrewedMission: Mission, @unchecked Sendable { ... }
Вызов async-функций из блока defer теперь тоже разрешён. Это убирает ограничение, из-за которого раньше часто приходилось писать неудобные обходные решения.
let uploadTask = Task {
try await storage.upload(file)
}
defer {
await logger.flush()
}
try await uploadTask.value
Более доступные инициализаторы для участников
Если структура содержит одновременно internal— и private-свойства, Swift теперь генерирует два почленных инициализатора: один включает приватные свойства и доступен только внутри файла, а второй не включает их и доступен во всём модуле. Раньше второй инициализатор приходилось писать вручную.
struct Briefing {
internal var topic: String
internal var scheduledAt: Date
private var attendees: [Person] = []
// Swift now generates both a private full init and an internal partial init
}
Дополнения в стандартной библиотеке
Защита от отмены задачи
Некоторые операции должны завершиться даже после отмены задачи, например сброс буфера файла, чтобы избежать повреждения данных. withTaskCancellationShield оборачивает участок кода, внутри которого Task.isCancelled всегда возвращает false.
extension EmergencyTransponder {
func sendSOS() {
withTaskCancellationShield {
radio.send(makeSOSPacket())
}
}
}
Держите экранированную область короткой и сосредоточьтесь на откате или завершении работы.
mapKeyedValues в словаре
Существующий mapValues предоставляет только значение в замыкании преобразования. Новый mapKeyedValues передает как ключ, так и значение.
let displayNames = missions.mapKeyedValues { mission, window in
makeDisplayName(for: mission, in: window)
}
Новый тип FilePath
В стандартную библиотеку добавлен тип FilePath, перенесенный из Swift System. Он корректно обрабатывает различия в представлении путей между платформами и последовательно анализирует компоненты, устраняя распространенный источник скрытых ошибок в кроссплатформенном коде.
var path: FilePath = "/Users/khoa/Documents"
path.components.append("Projects")
path.components.append("app")
print(path.components)
// [ "Users", "khoa", "Documents", "Projects", "app" ]
Что еще почитать
- Что нового в UIKit после WWDC26
- Что нового в SwiftUI после WWDC26
- Что нового в App Store после WWDC 26
-
Разработка4 недели назадГорячая перезагрузка AGSL-шейдеров без пересборки: пошаговое руководство для Compose
-
Новости3 недели назадВидео и подкасты о мобильной разработке 2026.21
-
Исследования4 недели назадКак Apple боролась с мошенничеством в App Store в 2025
-
Видео и подкасты для разработчиков3 недели назадN техник, которые улучшат работу видеоленты
