Это механизм динамического диспетчинга в Swift, используемый для работы с протоколами.
- Если структура или класс реализуют протокол, Swift создает Witness Table, хранящую указатели на методы.
- Это позволяет динамически вызывать методы, объявленные в протоколе, даже если тип не известен во время компиляции.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  В Swift есть несколько инструментов для работы с многопоточностью и параллельным выполнением кода. Вот основные из них:
GCD – это низкоуровневая технология, позволяющая управлять задачами (тасками) в очередях (
DispatchQueue).  DispatchQueue.global(qos: .background).async {
    print("Фоновый поток")
    
    DispatchQueue.main.async {
        print("Вернулись в главный поток")
    }
}OperationQueue – это более гибкая и объектно-ориентированная альтернатива GCD.
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 2 // Ограничение на 2 задачи одновременно
queue.addOperation {
print("Операция 1")
}
queue.addOperation {
print("Операция 2")
}
С
actor можно работать с потоками без гонок данных, потому что все его свойства защищены от одновременного доступа.actor Counter {
    private var value = 0
    
    func increment() {
        value += 1
    }
    func getValue() -> Int {
        return value
    }
}
let counter = Counter()
Task {
    await counter.increment()
    print(await counter.getValue()) // Потокобезопасный доступ
}С
async/await код становится читаемым и удобным.func fetchData() async -> String {
    try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 секунда задержки
    return "Данные загружены"
}
Task {
    let result = await fetchData()
    print(result)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  - HEAD — как GET, но без тела. Используется, чтобы узнать метаинформацию (например, размер файла или заголовки) без загрузки содержимого.
- GET — запрашивает данные с сервера. Не изменяет состояние сервера.
- POST — отправляет данные на сервер для создания нового ресурса. Неидемпотентен.
- PUT — отправляет данные для полного обновления существующего ресурса. Идемпотентен.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Структуры (
struct) – это один из основных типов данных в Swift. Они значимые (value type), то есть при передаче копируются, а не передаются по ссылке.  Value type – при передаче копируется (в отличие от классов)
Нет ARC (автоматического подсчета ссылок) – производительность выше
Могут иметь методы, свойства, инициализаторы
Работают с протоколами (protocol-oriented programming)
Не поддерживают наследование
struct Car {
    var model: String
    var year: Int
    func description() -> String {
        return "\(model) – \(year)"
    }
}
let car1 = Car(model: "Tesla", year: 2023)
var car2 = car1 // Создается копия
print(car1.description()) // Tesla – 2023
print(car2.description()) // Tesla – 2023
car2.year = 2024 // Изменяем car2, но car1 остается прежним
print(car1.year) // 2023
print(car2.year) // 2024По умолчанию методы не могут изменять свойства структуры. Чтобы изменить их внутри метода, нужно использовать
mutatingstruct Counter {
    var count = 0
    mutating func increment() {
        count += 1
    }
}
var counter = Counter()
counter.increment()
print(counter.count) // 1Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Отвечают за сопротивление сжатию UI-элемента в ограниченном пространстве. Элемент с более высоким приоритетом будет меньше сжиматься, чем элемент с более низким значением.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  NSManagedObjectID – это уникальный идентификатор объекта в Core Data, который остаётся неизменным на протяжении всего жизненного цикла объекта.  Используем
uriRepresentation() – это строка (URL), которая уникально идентифицирует объект.  func saveObjectID(_ object: NSManagedObject) {
    let objectID = object.objectID.uriRepresentation().absoluteString
    UserDefaults.standard.set(objectID, forKey: "savedObjectID")
}1. Получаем
URL из UserDefaults.  2. Преобразуем
URL в NSManagedObjectID.  3. Загружаем объект из Core Data.
func fetchSavedObjectID(context: NSManagedObjectContext) -> NSManagedObject? {
    guard let objectIDString = UserDefaults.standard.string(forKey: "savedObjectID"),
          let objectURL = URL(string: objectIDString) else { return nil }
    let objectID = context.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: objectURL)
    if let objectID = objectID {
        return context.object(with: objectID)
    }
    return nil
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  UIView — это высокоуровневая оболочка, которая управляет взаимодействием, событиями, отрисовкой, а CALayer — низкоуровневая графическая часть. Через UIView проще управлять UI и логикой, layer — для кастомной графики и анимаций.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Принцип OCP (Open-Closed Principle) гласит:
"Программные сущности должны быть открыты для расширения, но закрыты для модификации."
Это значит, что код должен позволять добавлять новый функционал без изменения существующего кода.
Меньше багов – изменения не ломают старый код.
Лучшая поддержка – новый функционал добавляется без переписывания старого.
Гибкость – можно расширять систему без изменения её базовой логики.
Допустим, у нас есть класс, который рисует фигуры:
class ShapeDrawer {
    func draw(shape: String) {
        if shape == "circle" {
            print("Рисуем круг")
        } else if shape == "square" {
            print("Рисуем квадрат")
        }
    }
}Лучше использовать наследование или протоколы, чтобы расширять функциональность, не меняя существующий код:
protocol Drawable {
    func draw()
}
class Circle: Drawable {
    func draw() {
        print("Рисуем круг")
    }
}
class Square: Drawable {
    func draw() {
        print("Рисуем квадрат")
    }
}
class ShapeDrawer {
    func draw(shape: Drawable) {
        shape.draw()
    }
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Это ситуация, когда value type (например, struct) находится внутри reference type (например, класса), и тогда доступ к нему уже регулируется по ссылке через обёртку.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  В Swift ключи в словаре (
Dictionary) должны быть уникальными и сравниваться между собой. Поэтому, если вы хотите использовать*свою структуру в качестве ключа, она должна соответствовать протоколу Hashable.  Структура должна соответствовать
Hashable  Должен быть реализован
hash(into:) или использовать Equatable + Hashable автоматически  Свойства структуры должны быть
Hashable (если String, Int, Double – все ок)  struct Person: Hashable {
    let id: Int
    let name: String
}
// Теперь можно использовать `Person` как ключ
var peopleAges: [Person: Int] = [
    Person(id: 1, name: "Alice"): 25,
    Person(id: 2, name: "Bob"): 30
]
// Доступ по ключу
let alice = Person(id: 1, name: "Alice")
print(peopleAges[alice] ?? "Не найдено") // 25Если нужно кастомное хеширование, можно реализовать
hash(into:):struct Person: Hashable {
    let id: Int
    let name: String
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)   // Используем только id для хеша
    }
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍1
  В основе Git Flow – несколько веток с разными ролями, чтобы команда могла параллельно разрабатывать новые фичи, исправлять баги и выпускать релизы.
-
main – содержит только стабильные версии.  -
develop – основная ветка разработки, в неё вливаются все новые фичи.  - Каждая новая фича создаётся в отдельной ветке
feature/*.  - После завершения сливается в
develop.  git checkout develop
git checkout -b feature/new-cool-feature
# Разработка...
git checkout develop
git merge feature/new-cool-feature
git branch -d feature/new-cool-feature
- Когда код стабилен, создаётся ветка
release/* от develop.  - Здесь можно тестировать и исправлять баги.
- После финального теста сливается в
main и develop.  git checkout develop
git checkout -b release/1.0
# Фиксим баги, тестируем...
git checkout main
git merge release/1.0
git tag -a v1.0 -m "Release 1.0"
git checkout develop
git merge release/1.0
git branch -d release/1.0
- Если критический баг в
main, создаём hotfix/*.  - После исправления вливаем в
main и в develop.  git checkout main
git checkout -b hotfix/urgent-bugfix
# Фиксим баг...
git checkout main
git merge hotfix/urgent-bugfix
git checkout develop
git merge hotfix/urgent-bugfix
git branch -d hotfix/urgent-bugfix
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍1
  Переменная хранит само значение, а не ссылку. Это значит, при копировании создаётся отдельная копия, и изменения в одной переменной не влияют на другую
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍2