ARC в Swift
🎉  Всех с прошедшим Днем программиста! И чтобы не забывать основы - принес статью про механизм подсчета ссылок.
❓  
⚠️  Циклы сильных ссылок (
🔗  
⚙️  ARC работает на уровне 
✔️  Автоматический подсчет ссылок упрощает управление памятью, избавляя разработчиков от необходимости вручную управлять ссылками, что делает код более лаконичным и понятным.
ARC (Automatic Reference Counting) - это метод управления памятью в Swift, который автоматически отслеживает количество сильных ссылок на объекты и освобождает их, когда счётчик достигает нуля.retain cycles) могут возникать, когда два объекта ссылаются друг на друга, что мешает ARC освободить память. Это может привести к утечкам памяти.Weak ссылки не учитываются ARC при подсчёте ссылок, что помогает избежать retain cycles, в то время как unowned ссылки никогда не становятся nil, но могут крашнуть приложение при обращении к уничтоженному объекту.SIL (Swift Intermediate Language), где компилятор автоматически добавляет инструкции подсчёта ссылок, что делает код более чистым и безопасным.Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥6❤2👍2
  Swift 6.2 Released
⚡️  Swift 6.2 выпущена 15 сентября. Кратко, что нового.
❓  Упрощенное написание безопасного параллельного кода с помощью новых атрибутов, таких как
🔒  В новой версии добавлены типы
🔥  Расширение Swift для VS Code теперь официально подтверждено и включает функции, такие как фоновая индексация и встроенная отладка с LLDB.
❓  Swift 6.2 теперь поддерживает WebAssembly, позволяя создавать приложения для браузеров и других сред выполнения.
⚙️  Библиотеки Swift 6.2 включают новый пакет
 @concurrent, и делает код однопоточным по умолчанию. InlineArray и Span, которые обеспечивают безопасный доступ к памяти и высокую производительность без дополнительных затрат. Subprocess для управления внешними процессами и улучшенный API для NotificationCenter.Please open Telegram to view this post
    VIEW IN TELEGRAM
  ⚡7👍2❤1🔥1
  Не могу не поделиться важной и крутой инфой: мой друг выпустил 10 часовой бесплатный курс!!! про iOS разработку для начинающих 🔥
Если вы начали изучать Swift – обязательно к просмотру. И не забывайте делиться с теми, кто тож хочет начать этот увлекательный путь.
https://www.youtube.com/watch?v=SUKocLwjA5k
  
  Если вы начали изучать Swift – обязательно к просмотру. И не забывайте делиться с теми, кто тож хочет начать этот увлекательный путь.
https://www.youtube.com/watch?v=SUKocLwjA5k
YouTube
  
  Swift - полный курс для начинающих iOS разработчиков. Это БАЗА – Теория, практика, домашки
  Swift - полный курс для начинающих. База для iOS разработчиков, которые хотят построить успешную карьеру
Тренировка собеседования по iOS разработке https://t.iss.one/emma_in_it_bot
Решение реальных задач по верстке из Big Tech с тестированием и ревью кода h…
Тренировка собеседования по iOS разработке https://t.iss.one/emma_in_it_bot
Решение реальных задач по верстке из Big Tech с тестированием и ревью кода h…
🔥8👍5❤2
  Как Swift Runtime влияет на производительность iOS-приложений
⚡️  Тут наши ребята рассказывают про производительность - супер объемный и полезный обзор. Вот лишь несколько моментов. 
⚙️  
‼️  Метод 
⚠️  Рекомендуется избегать использования 
🤫  Использование 
соответствия для каждого протокола.
💯  Рекомендую к прочтению.
Swift Runtime играет ключевую роль в производительности iOS-приложений, особенно в управлении памятью и проверке соответствия типов, что может значительно замедлить работу приложения.swift_conformsToProtocolMaybeInstantiateSuperclasses является узким местом производительности, так как он может занимать от 1 до 3 мс на каждом вызове, особенно при использовании операторов as? и as! или методов String(describing:) и String(reflecting:).String(describing:) и операторов as? и as!, а также минимизировать использование type-generic-constraint-ов для повышения производительности приложения.type-generic-constraint-ов может значительно замедлить приложение, так как каждый вызов метода swift_conformsToProtocolMaybeInstantiateSuperclasses требует проверки соответствия для каждого протокола.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍7🔥2
  Swift Default Value in String Interpolations
🔥  Swift 6.2 улучшает интерполяцию строк с опциональными значениями, позволяя использовать параметр значения по умолчанию.
❓  При интерполяции строк с опционалами  компилятор выдает предупреждение, если не указано значение по умолчанию.
🤫  Теперь можно использовать новый параметр по умолчанию в строке, чтобы она не зависела от типа опционального значения. Однако, он не будет работать с локализацией: 
LocalizedStringKey не поддерживает такой формат.// The count is not set
Text("The count is \(count, default: "not set")")
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍2
  Строки в Swift
❓  Строки в Swift представляют собой контейнеры для символов и являются типами значений, что отличает их от многих других языков программирования.
➡️  Для доступа к символам в строках Swift используется специальный тип индекса
🖥  Строки могут быть представлены в различных кодировках, таких как
➡️  Строки Swift могут быть конвертированы в
 String.Index, а не обычные целые числа, что связано с особенностями представления символов. unicodeScalars, utf16 и utf8, каждая из которых имеет свои особенности и количество кодовых точек. Сами же строки используют оптимизацию Copy-on-Write, что позволяет эффективно управлять памятью и ускорять доступ к данным. NSString и обратно, что позволяет использовать их в проектах, где смешиваются Swift и Objective-C.Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍4
  Command tools, threads and QoS
Почему супер навороченные новые мак не могут быстро сжать большую папку через🤕 
❓  macOS использует различные уровни 
ℹ️  Однопоточные процессы, такие как 
Почему супер навороченные новые мак не могут быстро сжать большую папку через
tar? 
Крайне интересная статья, которая поможет лучше разбираться в многопоточности на примере реальной задачи архивирования. Вот краткое содержание.QoS для распределения потоков по ядрам процессора, что влияет на производительность. QoS варьируется от 9 (background) до 33 (userInteractive).tar, значительно медленнее многопоточных альтернатив, которые могут использовать все доступные производительные ядра.Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍3
  Feature flags in Swift
🚩  
❓  По умолчанию в 
🔥  Создание перечисления 
ℹ️  Такой механизм следует рассматривать как временный инструмент и удалять флаги, когда функция готова. Рассмотрите возможность удаленной настройки для мгновенного включения или отключения функций. Крайне полезный инструмент. 
Feature flags в Swift позволяют включать и отключать определенные функциональности. В статье автор приводит в пример в зависимости от конфигурации сборки, таких как Debug, TestFlight и App Store.Xcode есть две конфигурации: Debug и Release. Рекомендуется создавать дубликаты для App Store и TestFlight для управления функциональностью.Distribution и структуры FeatureFlags позволяет управлять доступом к функциям в зависимости от текущей конфигурации сборки.public struct FeatureFlags: Sendable, Decodable {
    public let requirePaywall: Bool
    public let requireOnboarding: Bool
    public let featureX: Bool
    public init(distribution: Distribution) {
        switch distribution {
        case .debug:
            self.requirePaywall = true
            self.requireOnboarding = true
            self.featureX = true
        case .appstore:
            self.requirePaywall = true
            self.requireOnboarding = true
            self.featureX = false
        case .testflight:
            self.requirePaywall = false
            self.requireOnboarding = true
            self.featureX = true
        }
    }
}Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥2
  How to unwrap [weak self] in Swift Concurrency Tasks?
🔍  В Swift, использование 
❌  Создание неструктурированного 
✔️  Для предотвращения сильного удержания 
❓  При выполнении длительных задач, таких как загрузка нескольких страниц, перемещение 
[weak self] в замыканиях помогает избежать циклов удержания, но не всегда необходимо, особенно для не-escaping замыканий.Task может привести к утечкам памяти, если [weak self] используется неправильно, так как Task начинает выполняться сразу после его создания.Task { [weak self] in
  guard  let self else { return } // это не решает проблему
  let data = await loadData()
  let models = await processData(data)
}self в Task, рекомендуется проверять наличие self внутри тела цикла или использовать self? для избежания распаковки.guard let self внутрь цикла позволяет избежать удержания self дольше, чем это необходимо.Task { [weak self] in
  let data = await loadData()
  guard self != nil else { return }
  guard let models = await self?.processData(data) else {
    return
  }
  // use models
}Please open Telegram to view this post
    VIEW IN TELEGRAM
  ⚡4👎2🔥1
  Derived Data: 5 Things iOS Developers Do Wrong
😐  Многие разработчики iOS не понимают, для чего предназначена папка 
❓  Удаление всей папки 
ℹ️  Инструменты, такие как 
🔍  Разработчики должны исследовать содержимое папки сборки для выявления неиспользуемых ресурсов и оптимизации размера приложения.
🖥  
Derived Data, что может привести к неэффективному использованию её возможностей.Derived Data может замедлить процесс сборки, так как каждый проект имеет свою собственную папку, и удаление её требует повторной компиляции всех зависимостей.RocketSim, могут помочь командам отслеживать время сборки и выявлять узкие места, что может значительно повысить производительность.Xcode предоставляет простой способ доступа к папке Derived Data через настройки, что облегчает её использование.Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍3
  Массивы в Swift
🟢  Принес очередную базу.
ℹ️  Массивы в 
❓  Добавление элементов в массив происходит за амортизированное константное время, однако при расширении массива может потребоваться больше времени из-за копирования элементов.
⚠️  Массивы в 
👀  Они представляют собой обертку над буфером, который хранит данные в куче. В зависимости от наличия 
❓  Swift реализует механизм 
❓  
Swift - это структуры данных, которые хранят коллекции элементов одного типа и поддерживают доступ по индексу за O(1).Swift являются типами значений, что означает, что изменения в одном массиве не затрагивают его копии. Для работы с ссылочными типами необходимо использовать глубокое копирование.Objective-C runtime, используются разные типы буферов.Copy-on-Write, который позволяет избежать ненужного копирования данных до момента их изменения.ArraySlice позволяет работать с подмножеством элементов массива без их копирования, что экономит память и время.Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍5❤1
  Разбираемся с existential container в Swift
❓  
⚙️  
❓  
❗️  В отличие от дженериков, которые используют статическую диспетчеризацию, 
✔️  Рекомендуется использовать дженерики по умолчанию, если нет необходимости в динамическом определении типа, чтобы избежать излишнего использования памяти и увеличения размера бинарного файла.
Existential container — это структура данных в Swift, которая хранит значения типов, скрытых за протоколами, и используется для динамического вызова методов и управления жизненным циклом значений.Existential container для non class-constrained типов занимает 5 машинных слов (40 байт) и состоит из 24 байт данных, указателя на метаданные типа и указателя на таблицу свидетельств протокола.Value witness table (VWT) описывает операции с конкретными типами, включая инициализацию, копирование и уничтожение значений, что позволяет компилятору генерировать соответствующий код для этих операций.existential container применяет динамическую диспетчеризацию, что требует выделения памяти в куче для значений больше 3 байт.Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥5😁1
  How to Use OptionSet in Swift with code samples
ℹ️  
🖥  В примере кода создается структура 
❓  Хотя можно использовать enum для аналогичных задач, 
✔️  
OptionSet — это протокол в Swift, который представляет опции в виде битов, позволяя комбинировать несколько значений и выполнять операции, такие как объединение и пересечение.TasksListOptions, которая использует OptionSet для определения опций отображения задач, таких как фильтр, поиск и сортировка.struct TasksListOptions: OptionSet {
    let rawValue: Int
    static let showFilter = TasksListOptions(rawValue: 1 << 0)
    static let showSearch = TasksListOptions(rawValue: 1 << 1)
    static let showSort = TasksListOptions(rawValue: 1 << 2)
    static let showLayoutSelector = TasksListOptions(rawValue: 1 << 3)
}OptionSet более эффективен и предоставляет встроенные функции для работы с опциями без дополнительного кода.OptionSet является предпочтительным инструментом для конфигурации функций, стилей или разрешений в Swift, обеспечивая компактность и производительность.Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤5
  Using Observations to observe @Observable model properties
🆕  С 
🔍  Объект 
❗️  Важно использовать 
⚠️  При использовании Observations можно пропустить значения, если они производятся быстрее, чем вы их обрабатываете, поэтому рекомендуется реализовать собственное буферизование.
➡️  Новая система 
Xcode 26 и Swift 6.2 появилась возможность использовать объект Observations для наблюдения за свойствами моделей @Observable, что упрощает процесс наблюдения вне SwiftUI.Observations позволяет создать AsyncSequence, который будет эмитировать значения при изменении наблюдаемых свойств, таких как count в модели Counter.[weak self] в замыкании Observations, чтобы избежать циклов удержания, что может привести к утечкам памяти.Observations предлагает did set semantics, в отличие от withObservationTracking, который использует will set semantics, что улучшает реакцию на изменения.@Observable
class Counter {
var count: Int
}
class CounterObserver {
let counter: Counter
init(counter: Counter) {
self.counter = counter
}
func observe() {
Task { [weak self] in
let values = Observations { [weak self] in
guard let self else { return 0 }
return self.counter.count
}
for await value in values {
guard let self else { break }
print("counter.count: \(value)")
}
}
}
}
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥4
  Detecting Text Language with NLLanguageRecognizer in Swift
ℹ️  Для определения доминирующего языка текста используется структура 
❓  
⚙️  Можно добавить возможность возвращать оценки уверенности в предсказании языка и использовать языковые подсказки для повышения точности распознавания в многоязычных приложениях.
✔️  
LanguageDetector, которая инициализирует NLLanguageRecognizer, обрабатывает строку и возвращает код языка в формате ISO 639-1.NLLanguageRecognizer использует статистические модели, обученные на больших текстовых корпусах, и лучше всего работает с полными предложениями или абзацами, а не с короткими фразами.NLLanguageRecognizer — это мощный API, который позволяет интегрировать определение языка в приложение без необходимости в серверных вызовах и задержках.import NaturalLanguage
struct LanguageDetector {
static func languageCode(for text: String) -> String? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(text)
if let language = recognizer.dominantLanguage {
return language.rawValue // "en", "ru", "de", etc.
}
return nil
}
}
static func detectLanguage(for text: String) -> (code: String, confidence: Double)? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(text)
guard let language = recognizer.dominantLanguage else { return nil }
let hypotheses = recognizer.languageHypotheses(withMaximum: 1)
let confidence = hypotheses[language] ?? 0
return (language.rawValue, confidence)
}
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ⚡3
  Сам себе Шерлок: 7 способов найти логи и поймать баг на iOS
Очередная база - лонгрид про логи⚙️ 
🖥  Статья описывает 7 проверенных способов сбора логов на iOS, включая использование .ips файлов, 
❓  Логи делятся на креш-отчёты, диагностические и аналитические данные, которые помогают выявить причины сбоев и проблем с производительностью приложения.
❓  Для работы с логами могут потребоваться инструменты, такие как 
👀 Логи помогают разработчикам и тестировщикам убедиться в вызове функций, отслеживать сетевые запросы и выявлять ошибки, которые не отображаются на UI.
⚠️  Рекомендуется собирать логи сразу после инцидента, так как старые .ips файлы автоматически удаляются системой.
Очередная база - лонгрид про логи
log collect CLI, Xcode и утилиты Console.Xcode, libimobiledevice и Apple Configurator, а также доступ к устройству по проводу или Wi-Fi.Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥3👍1
  Testing Private Members in Swift with @_private(sourceFile:)
👀  Атрибут 
❓  Ранее разработчики могли либо делать приватные члены внутренними, что нарушает инкапсуляцию, либо тестировать только через публичные API, что усложняет отладку.
⚙️  Для использования 
⚠️  Рекомендуется использовать 
@_private(sourceFile:) в Swift позволяет тестировать приватные члены классов, обходя контроль доступа, что полезно для написания более точных юнит-тестов.@_private необходимо включить приватные импорты в модуле с помощью флага -enable-private-imports и использовать условную компиляцию в тестах.@_private только в тестах, оборачивая его в условные флаги компиляции для обеспечения гибкости и возможности отключения при изменениях в Swift.Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤🔥1❤1🔥1
  На днях команда Swift выпустила…
Странный шаг, честно говоря.
KMP вроде бы не стал панацей, с чего вдруг это сработает в обратную сторону… Swift SDK для Android доступен для загрузки с установщика Windows или отдельно для Linux и macOS.Swift для Android.Swift Package Index уже совместимы с Android, что упрощает портирование существующих пакетов.Android разрабатывает документ видения, который определит приоритетные направления для будущей работы с Swift на Android.Please open Telegram to view this post
    VIEW IN TELEGRAM
  🤯7👍5❤🔥1
  Thread-Safe Classes: GCD vs Actors
⚙️  Многопоточность и гонки данных являются распространенными проблемами в программировании, особенно при работе с общими ресурсами, такими как словари.
➡️  Использование конкурентной очереди и синхронных/асинхронных вызовов позволяет создать потокобезопасный кэш, предотвращая гонки данных и обеспечивая целостность состояния.
➡️  Лучшей практикой является использование барьеров для обеспечения эксклюзивного доступа к ресурсам при записи, что позволяет одновременно выполнять чтение.
➡️  Акторы обеспечивают безопасность параллелизма, позволяя только одной задаче одновременно получать доступ к изолированному состоянию, что упрощает синхронизацию.
✔️  Сравнение различных подходов к потокобезопасности показывает, что использование акторов является наиболее современным и безопасным методом для работы с многопоточностью в Swift.
Хорошая статья с кучей примеров, рекомендую к прочтению.👍 
Хорошая статья с кучей примеров, рекомендую к прочтению.
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍3❤🔥1
  Singletons with Swift Concurrency
🖥  Синглтоны представляют собой глобальное состояние, что делает их источником проблем в многопоточном окружении, так как они не являются потокобезопасными.
⚠️  Рекомендуется избегать использование синглтонов и вместо этого использовать паттерн корня компоновки или передавать аргументы в функции.
🔍  Аннотация 
➡️  Среди альтернатив синглтонам рассматриваются кастомные актеры, использование блокировок и аннотация 
😲  А вы знали, что у Apple есть тоже документация по синглтонам?
@MainActor позволяет гарантировать потокобезопасный доступ к синглтону, что упрощает аудит и выявление проблем в коде.@unchecked Sendable, но каждая из этих опций имеет свои недостатки.Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍2
  Understanding task cancellation and lifetimes in Swift concurrency
ℹ️  В Swift 
➡️  Несструктурированные задачи, созданные с помощью 
➡️  При работе с долгоживущими задачами, такими как 
⚠️  Отмена задач в Swift не останавливает их немедленно, а устанавливает флаг отмены, который асинхронные операции могут проверять для корректного завершения.
structured concurrency связывает время жизни асинхронной работы с областью, в которой она была создана, автоматически отменяя задачи при завершении этой области.Task { ... }, работают независимо и требуют ручной отмены, в то время как Task.detached выполняется полностью независимо от контекста вызова.AsyncStream, важно управлять временем жизни задачи, чтобы избежать бесконечного выполнения.Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍3