Swift | Вопросы собесов
2.13K subscribers
28 photos
951 links
Download Telegram
🤔 Как работают push нотификации?

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

🚩Как работают push-уведомления

1⃣Регистрация устройства
Когда приложение устанавливается и запускается на устройстве, оно регистрируется для получения push-уведомлений. Для этого приложение отправляет запрос к Apple Push Notification Service (APNs) с запросом на получение уникального токена устройства (device token).

2⃣Получение токена устройства
APNs генерирует уникальный токен для устройства и отправляет его обратно приложению. Приложение затем передает этот токен на свой сервер.

3⃣Отправка уведомления на сервер
Когда необходимо отправить push-уведомление, сервер приложения формирует сообщение, включающее содержимое уведомления и токен устройства, и отправляет его на APNs.

4⃣Доставка уведомления
APNs принимает сообщение от сервера, определяет устройство по токену и отправляет уведомление на это устройство.

5⃣Получение уведомления на устройстве
Когда устройство получает уведомление, операционная система отображает его пользователю. Если пользователь взаимодействует с уведомлением, приложение может выполнить определенные действия, такие как открытие конкретного экрана.

🚩Пример кода для регистрации устройства

В AppDelegate
import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Запрос разрешения на отправку уведомлений
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
return true
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Преобразуем токен в строку
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")

// Отправляем токен на сервер
// serverAPI.registerDeviceToken(token)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register: \(error)")
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 В чем заключается суть оптимизации?

Это улучшение производительности приложения за счёт уменьшения времени выполнения, потребления памяти или других ресурсов.
1. Основа — выявление узких мест с помощью профайлеров.
2. Важно оптимизировать только критические участки, чтобы не усложнять код.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое модификаторы в SwiftUI?

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

🚩Основные модификаторы

🟠Фон (background)
Изменяет фон представления.
Text("Привет, мир!")
.background(Color.yellow)


🟠Границы (border)
Добавляет границу вокруг представления.
Text("Привет, мир!")
.border(Color.red, width: 2)


🟠Отступы (padding)
Добавляет отступы вокруг содержимого представления.
Text("Привет, мир!")
.padding()


🟠Тень (shadow)
Добавляет тень к представлению.
Text("Привет, мир!")
.shadow(color: .black, radius: 2, x: 0, y: 2)


🟠Угловой радиус (cornerRadius)
Закругляет углы представления.
Text("Привет, мир!")
.background(Color.blue)
.cornerRadius(10)


🟠Размеры (frame)
Устанавливает размеры представления.
Text("Привет, мир!")
.frame(width: 200, height: 50)


Пример использования нескольких модификаторов
import SwiftUI

struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.padding() // Добавляем отступы
.background(Color.yellow) // Фон желтого цвета
.cornerRadius(10) // Закругляем углы
.shadow(color: .gray, radius: 5, x: 0, y: 5) // Добавляем тень
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как можно решить проблему с долгой необоснованной прогрузкой картинок?

1. Использовать кэширование изображений с помощью библиотек вроде SDWebImage.
2. Загружать изображения асинхронно, избегая блокировки основного потока.
3. Применять сжатие или адаптивные форматы изображений.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что будет если применить модификатор к вью?

Применение модификатора к вью в SwiftUI изменяет его внешний вид или поведение. Каждый модификатор возвращает новое представление с измененными свойствами, не изменяя исходное представление. Это позволяет создавать сложные пользовательские интерфейсы, применяя цепочки модификаторов.

🚩Что происходит при применении модификатора

🟠Изменение внешнего вида
Модификаторы могут изменять визуальные характеристики вью, такие как цвет, шрифт, отступы и границы.
Text("Привет, мир!")
.padding() // Добавляет отступы вокруг текста
.background(Color.yellow) // Устанавливает желтый фон
.cornerRadius(10) // Закругляет углы текста


🟠Изменение поведения
Модификаторы могут изменять поведение вью, такие как обработка событий и взаимодействие.
Button(action: {
print("Кнопка нажата")
}) {
Text("Нажми меня")
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)


🟠Компоновка
Модификаторы могут изменять размеры и позиционирование вью.
Text("Привет, мир!")
.frame(width: 200, height: 50) // Устанавливает размеры вью
.padding()
.background(Color.green)


Пример с пояснением
import SwiftUI

struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.padding() // Добавляет отступы вокруг текста
.background(Color.yellow) // Устанавливает желтый фон
.cornerRadius(10) // Закругляет углы текста
.shadow(color: .gray, radius: 5, x: 0, y: 5) // Добавляет тень
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🤔 Какая разница между semaphore и mutex?

1. Semaphore: синхронизирует доступ к ресурсу, позволяя определённое количество потоков одновременно. Например, для 3 потоков используется семафор с разрешениями 3.
2. Mutex: обеспечивает эксклюзивный доступ к ресурсу для одного потока.
3. Основное отличие в уровне параллелизма: mutex работает с одним потоком, а semaphore с несколькими.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
🤔 Что такое ViewModifier?

Это протокол, который позволяет создавать собственные модификаторы для вьюшек. Он позволяет инкапсулировать повторяющиеся изменения внешнего вида и поведения вью в отдельные, легко переиспользуемые компоненты. Это помогает сократить дублирование кода и улучшает читаемость и поддерживаемость приложения.

🚩Создание ViewModifier

Чтобы создать собственный модификатор, нужно реализовать протокол ViewModifier, который требует определения метода body(content:), возвращающего измененное представление.

🚩Пример создания ViewModifier

Допустим, мы хотим создать модификатор, который добавляет отступы, фон, закругленные углы и тень к вью.
import SwiftUI

// Создаем кастомный модификатор
struct CustomModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding() // Добавляем отступы
.background(Color.yellow) // Устанавливаем фон
.cornerRadius(10) // Закругляем углы
.shadow(color: .gray, radius: 5, x: 0, y: 5) // Добавляем тень
}
}

extension View {
func customStyle() -> some View {
self.modifier(CustomModifier())
}
}

struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.customStyle() // Применяем наш кастомный модификатор
}
}


🚩Объяснение

1⃣Создание структуры, соответствующей протоколу ViewModifier
   struct CustomModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.yellow)
.cornerRadius(10)
.shadow(color: .gray, radius: 5, x: 0, y: 5)
}
}


2⃣Расширение View для удобного использования модификатора
   extension View {
func customStyle() -> some View {
self.modifier(CustomModifier())
}
}


3⃣Применение кастомного модификатора в представлении
   struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.customStyle()
}
}


🚩Плюсы

Повторное использование кода
Модификаторы позволяют инкапсулировать часто используемые изменения и применять их в разных частях приложения.
Чистота и читаемость кода
Применение модификаторов упрощает и сокращает код, делая его более читаемым.
Модульность
Выделение стилей и поведения в отдельные модификаторы улучшает структуру кода и упрощает его поддержку.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 В чем плюсы VIPER?

1. Чистая архитектура: чёткое разделение ответственности между модулями (View, Interactor, Presenter, Entity, Router).
2. Улучшенная тестируемость: каждый модуль легко тестируется независимо.
3. Масштабируемость: упрощается добавление новых функций без влияния на существующий код.
4. Поддерживаемость: из-за чёткого разграничения слоёв снижается сложность сопровождения.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Что такое property wrapper?

Это способ добавить дополнительное поведение к свойствам без дублирования кода. Они позволяют инкапсулировать логику и применять её к различным свойствам, упрощая управление состоянием и поведением.

🚩Создание и использование property wrapper

1⃣Создание обёртки свойства
@propertyWrapper
struct Logging<Value> {
private var value: Value

var wrappedValue: Value {
get { value }
set {
print("Значение изменилось с \(value) на \(newValue)")
value = newValue
}
}

init(wrappedValue: Value) {
self.value = wrappedValue
}
}


2⃣Использование обёртки свойства
struct User {
@Logging var name: String
@Logging var age: Int
}

var user = User(name: "Алексей", age: 25)
user.name = "Иван" // Консоль: Значение изменилось с Алексей на Иван
user.age = 26 // Консоль: Значение изменилось с 25 на 26


🚩Основные концепции property wrapper

🟠wrappedValue
Основное свойство, которое обёртка обрабатывает. При чтении и записи этого свойства выполняется дополнительная логика, определённая в обёртке.

🟠init(wrappedValue:)
Инициализатор для установки начального значения свойства. Этот инициализатор делает возможным использование обёртки при объявлении свойств.

🚩Встроенные property wrapper в Swift

Swift предоставляет несколько встроенных обёрток свойств, которые широко используются в SwiftUI и Combine.

1⃣@State
Управляет состоянием внутри вью.
   struct ContentView: View {
@State private var counter = 0

var body: some View {
VStack {
Text("Счётчик: \(counter)")
Button("Увеличить счётчик") {
counter += 1
}
}
}
}


2⃣@Published
Объявляет свойство, которое оповещает подписчиков о своих изменениях.
   class ViewModel: ObservableObject {
@Published var message: String = "Привет"
}


3⃣@ObservedObject
Используется для наблюдения за объектом, который реализует протокол ObservableObject.
   struct ContentView: View {
@ObservedObject var viewModel = ViewModel()

var body: some View {
Text(viewModel.message)
}
}


🚩Плюсы

Повторное использование кода
Обёртки позволяют инкапсулировать повторяющуюся логику и применять её к различным свойствам.
Чистота и читаемость кода
Использование обёрток делает код более чистым и удобным для чтения.
Инкапсуляция
Логика управления состоянием и поведением свойств инкапсулируется внутри обёртки, что делает её независимой и легко тестируемой.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как синхронизировать данные между потоками (Как синхронизировать контекст)?

1. Использовать GCD (Grand Central Dispatch) с функциями sync и async для выполнения задач в очередях.
2. Применять мьютексы или семафоры для управления доступом к ресурсам.
3. Использовать NSLock или DispatchQueue.sync для работы с общими данными.
4. Применять атомарные операции (OSAtomic, DispatchSemaphore) для минимизации конфликтов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Назовите property wrapper, которые объявляют reference семантику?

В Swift property wrappers, которые объявляют reference семантику, позволяют объектам, обёрнутым этими обёртками, сохранять ссылочную семантику. Это значит, что при передаче таких объектов они будут передаваться по ссылке, а не по значению, как это обычно происходит со структурами.

🚩Основные property wrapper с reference семантикой

🟠@ObservedObject
Используется для отслеживания изменений в объекте, который реализует протокол ObservableObject. Когда такие объекты изменяются, представления, которые наблюдают за ними, автоматически обновляются.
import SwiftUI
import Combine

class ViewModel: ObservableObject {
@Published var message: String = "Привет"
}

struct ContentView: View {
@ObservedObject var viewModel = ViewModel()

var body: some View {
Text(viewModel.message)
}
}


🟠@StateObject
Этот property wrapper используется для инициализации и хранения экземпляра объекта, который реализует ObservableObject, обеспечивая правильное управление жизненным циклом объекта в пределах вью. Он гарантирует, что объект будет инициализирован один раз и не будет уничтожен при повторном рендеринге вью.
import SwiftUI
import Combine

class ViewModel: ObservableObject {
@Published var message: String = "Привет"
}

struct ContentView: View {
@StateObject var viewModel = ViewModel()

var body: some View {
Text(viewModel.message)
}
}


🟠@EnvironmentObject
Используется для передачи данных через иерархию представлений, чтобы любое представление в иерархии могло получить доступ к объекту. Этот объект должен быть доступен в окружающей среде представления.
import SwiftUI
import Combine

class ViewModel: ObservableObject {
@Published var message: String = "Привет"
}

struct ParentView: View {
@StateObject var viewModel = ViewModel()

var body: some View {
ChildView()
.environmentObject(viewModel)
}
}

struct ChildView: View {
@EnvironmentObject var viewModel: ViewModel

var body: some View {
Text(viewModel.message)
}
}


🚩Отличия между @ObservedObject, @StateObject и @EnvironmentObject

🟠@ObservedObject
Используется для наблюдения за объектом, который создаётся и управляется вне текущего представления.

🟠@StateObject
Используется для создания и управления объектом в текущем представлении, обеспечивая правильное управление его жизненным циклом.

🟠@EnvironmentObject
Используется для передачи объектов через несколько представлений, обеспечивая доступ к ним в любом представлении иерархии.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какие анимации есть?

1. Базовые анимации: изменения свойств (например, opacity, transform) через CABasicAnimation.
2. Ключевые кадры: CAKeyframeAnimation для сложных траекторий.
3. Групповые анимации: CAAnimationGroup для одновременного выполнения нескольких анимаций.
4. UIView-анимации: простые и удобные для UI (например, UIView.animate).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Назовите property wrapper, которые объявляют value семантику?

Property wrappers с value семантикой в Swift работают с типами, которые копируются при присваивании. Это означает, что при передаче таких объектов создаются их копии, и изменения в одной копии не влияют на другие. В Swift такие property wrappers часто используются для управления состоянием и других аспектов данных, которые должны копироваться при изменении.

🚩Основные property wrapper с value семантикой

🟠@State
Используется для хранения состояния в пределах представления. Когда состояние изменяется, представление автоматически обновляется для отображения нового состояния.
import SwiftUI

struct ContentView: View {
@State private var counter = 0

var body: some View {
VStack {
Text("Счётчик: \(counter)")
Button("Увеличить счётчик") {
counter += 1
}
}
}
}


🟠@Binding
Используется для создания связи между источником данных и представлением, позволяя передавать состояние между представлениями. @Binding позволяет двум представлениям разделять одно и то же состояние.
import SwiftUI

struct ParentView: View {
@State private var counter = 0

var body: some View {
ChildView(counter: $counter)
}
}

struct ChildView: View {
@Binding var counter: Int

var body: some View {
Button("Увеличить счётчик") {
counter += 1
}
}
}


🟠@AppStorage
Используется для хранения значений в UserDefaults. Позволяет легко сохранять и извлекать данные из постоянного хранилища.
import SwiftUI

struct ContentView: View {
@AppStorage("username") private var username: String = "Гость"

var body: some View {
VStack {
Text("Имя пользователя: \(username)")
Button("Изменить имя") {
username = "Алексей"
}
}
}
}


🟠@SceneStorage
Используется для хранения данных, специфичных для сцены, которые сохраняются и восстанавливаются при сворачивании и развертывании сцены.
import SwiftUI

struct ContentView: View {
@SceneStorage("note") private var note: String = ""

var body: some View {
TextField("Введите заметку", text: $note)
.padding()
}
}


🚩Отличия между property wrappers с value семантикой

🟠@State
Управляет состоянием в пределах одного представления.
🟠@Binding
Создаёт связь между состоянием в разных представлениях, позволяя одному представлению изменять состояние другого.
🟠@AppStorage
Хранит данные в UserDefaults, позволяя сохранять и восстанавливать их между сеансами приложения.
🟠@SceneStorage
Хранит данные, специфичные для сцены, которые сохраняются при сворачивании и развертывании сцены.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Какие бывают очереди?

1. Серийные (serial): задачи выполняются последовательно.
2. Параллельные (concurrent): задачи выполняются одновременно.
3. Главная очередь (main queue): предназначена для обновления UI.
4. Глобальные очереди (global queues): используются для фоновых задач.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как сделать класс наблюдаемым (начиная с iOS 17)?

Начиная с iOS 17, Apple представила новый способ сделать класс наблюдаемым с помощью атрибута @Observable и свойства @Published. Этот подход упрощает создание наблюдаемых объектов и улучшает интеграцию с SwiftUI.

🚩Создание наблюдаемого класса с использованием @Observable

1⃣Импортируем необходимые модули
import SwiftUI


2⃣Создаем класс и добавляем атрибут @Observable
@Observable
class ViewModel {
@Published var message: String = "Привет, мир!"
}


3⃣Используем наблюдаемый объект в SwiftUI
Теперь мы можем использовать наш наблюдаемый объект в SwiftUI, и представление будет автоматически обновляться при изменении свойств, помеченных как @Published.
struct ContentView: View {
@StateObject private var viewModel = ViewModel()

var body: some View {
VStack {
Text(viewModel.message)
Button("Изменить сообщение") {
viewModel.message = "Привет, SwiftUI!"
}
}
}
}


🚩Пример с пояснением

Полный пример использования наблюдаемого класса в SwiftUI
import SwiftUI

@Observable
class ViewModel {
@Published var message: String = "Привет, мир!"
}

struct ContentView: View {
@StateObject private var viewModel = ViewModel()

var body: some View {
VStack {
Text(viewModel.message)
Button("Изменить сообщение") {
viewModel.message = "Привет, SwiftUI!"
}
}
}
}


Пример использования @EnvironmentObject
import SwiftUI

@Observable
class ViewModel {
@Published var message: String = "Привет, мир!"
}

struct ParentView: View {
@StateObject private var viewModel = ViewModel()

var body: some View {
ChildView()
.environmentObject(viewModel)
}
}

struct ChildView: View {
@EnvironmentObject var viewModel: ViewModel

var body: some View {
VStack {
Text(viewModel.message)
Button("Изменить сообщение") {
viewModel.message = "Привет, SwiftUI!"
}
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1👾1
🤔 Какие способы передачи данных есть?

1. Прямой вызов: через свойства или методы объекта.
2. Делегаты: передача данных через протоколы.
3. Замыкания: использование callback-функций.
4. Уведомления: через NotificationCenter.
5. Кросс-контроллеры: с использованием segue или Dependency Injection.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Состояние сцены и переход (Scene phases and transitions)?

Сцены и фазы переходов (Scene phases and transitions) — важные аспекты управления состоянием приложения в SwiftUI, особенно когда речь идет о многозадачности и жизненном цикле приложения. SwiftUI предоставляет механизмы для обработки этих состояний и переходов через специальные property wrappers и API.

🚩Состояние сцены (Scene Phases)

🟠active
Приложение активно и отображает контент на экране.
🟠inactive
Приложение находится на переднем плане, но не взаимодействует с пользователем (например, при входящем вызове).
🟠background
Приложение находится в фоне и не отображается на экране.

Пример использования @Environment(\.scenePhase)
import SwiftUI

struct ContentView: View {
@Environment(\.scenePhase) var scenePhase

var body: some View {
Text("Привет, мир!")
.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .active:
print("Сцена активна")
case .inactive:
print("Сцена неактивна")
case .background:
print("Сцена в фоне")
@unknown default:
print("Неизвестное состояние сцены")
}
}
}
}


🚩Переходы между фазами сцены (Transitions)

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

Для приложений, использующих UIKit и SwiftUI вместе, обработка фаз сцены может выполняться в классе SceneDelegate.
import UIKit
import SwiftUI

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = ContentView()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}

func sceneDidBecomeActive(_ scene: UIScene) {
// Сцена стала активной
print("Сцена активна")
}

func sceneWillResignActive(_ scene: UIScene) {
// Сцена станет неактивной
print("Сцена неактивна")
}

func sceneDidEnterBackground(_ scene: UIScene) {
// Сцена перешла в фоновый режим
print("Сцена в фоне")
}

func sceneWillEnterForeground(_ scene: UIScene) {
// Сцена перейдет в передний план
print("Сцена на переднем плане")
}
}


🚩Плюсы

Сохранение состояния
Позволяет сохранять важные данные, когда приложение переходит в фоновый режим, и восстанавливать их при возвращении.
Оптимизация ресурсов
Позволяет освобождать ресурсы, когда приложение не активно, и выделять их, когда оно становится активным.
Улучшение UX
Обеспечивает плавный и предсказуемый опыт для пользователя при смене состояний приложения.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какие виды диспетчеризации существуют Static Dispatch: метод вызова известен на этапе компиляции?

1. Dynamic Dispatch: метод определяется во время выполнения через таблицу виртуальных функций (vtable).
2. Direct Dispatch: прямой вызов метода без участия vtable.
3. Protocol Witness Table (PWT): используется для вызовов методов, реализованных через протоколы.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какие модификаторы изменяют View life cycle events?

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

🟠`onAppear`
Выполняет действие, когда представление появляется на экране.
🟠`onDisappear`
Выполняет действие, когда представление исчезает с экрана.
🟠`task`
Выполняет асинхронное действие при появлении представления на экране.
🟠`onChange`
Реагирует на изменения определенного состояния или значения.
🟠`onReceive`
Реагирует на обновления из Publisher.

🚩Модификаторы жизненного цикла представлений

🟠onAppear
onAppear выполняет действие, когда представление появляется на экране.
struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.onAppear {
print("Представление появилось на экране")
}
}
}


🟠onDisappear
onDisappear выполняет действие, когда представление исчезает с экрана.
struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.onDisappear {
print("Представление исчезло с экрана")
}
}
}


🟠task
task выполняет асинхронное действие при появлении представления на экране. Это полезно для загрузки данных или выполнения других асинхронных задач.
struct ContentView: View {
var body: some View {
Text("Привет, мир!")
.task {
await loadData()
}
}

func loadData() async {
// Асинхронная загрузка данных
print("Данные загружаются")
}
}


🟠onChange
onChange реагирует на изменения определенного состояния или значения.
struct ContentView: View {
@State private var counter = 0

var body: some View {
VStack {
Text("Счётчик: \(counter)")
Button("Увеличить счётчик") {
counter += 1
}
}
.onChange(of: counter) { newValue in
print("Счётчик изменился на \(newValue)")
}
}
}


🟠onReceive
onReceive реагирует на обновления из Publisher. Это полезно для обработки данных из Combine.
import Combine

struct ContentView: View {
@State private var data: String = "Загрузка..."
let publisher = PassthroughSubject<String, Never>()

var body: some View {
Text(data)
.onReceive(publisher) { value in
data = value
}
}
}


🚩Плюсы

Управление состоянием
Легко управлять состоянием представлений в различные моменты их жизненного цикла.
Асинхронные задачи
Выполнение асинхронных задач, таких как загрузка данных, при появлении представлений на экране.
Обработка изменений
Реакция на изменения состояний и значений в представлении.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Зачем нужен словарь?

Словарь (dictionary) используется для хранения данных в формате ключ-значение. Это позволяет быстро искать, добавлять и удалять элементы по ключу, обеспечивая оптимальную производительность (обычно O(1)).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2