В Swift value типы (структуры и перечисления) обычно хранятся в стеке, что обеспечивает их высокую производительность. Однако в некоторых случаях value типы могут стать reference, то есть храниться в куче. Это происходит в следующих ситуациях:
Когда значение типа захватывается замыканием, оно может быть перемещено в кучу для обеспечения корректного управления памятью и жизненного цикла.
struct MyStruct {
var value: Int
}
func createClosure() -> () -> Int {
let myStruct = MyStruct(value: 42)
return { myStruct.value }
}
let closure = createClosure()
print(closure()) // Output: 42В этом примере
myStruct захватывается замыканием, что приводит к его размещению в куче.Когда value тип заворачивается в объект класса, он хранится в куче.
class Box<T> {
var value: T
init(_ value: T) {
self.value = value
}
}
struct MyStruct {
var value: Int
}
let boxedStruct = Box(MyStruct(value: 42))
print(boxedStruct.value.value) // Output: 42В этом примере структура
MyStruct обернута в объект класса Box, что приводит к её размещению в куче.Когда value тип используется в качестве свойства класса, он будет храниться в куче вместе с экземпляром класса.
struct MyStruct {
var value: Int
}
class MyClass {
var myStruct: MyStruct
init(myStruct: MyStruct) {
self.myStruct = myStruct
}
}
let instance = MyClass(myStruct: MyStruct(value: 42))
// instance.myStruct хранится в кучеВ этом примере структура
MyStruct является свойством класса MyClass, поэтому её экземпляры хранятся в куче вместе с экземплярами MyClass.Коллекции, такие как массивы, словари и множества, хранящие value типы, могут размещать эти значения в куче, если коллекция становится слишком большой.
struct MyStruct {
var value: Int
}
let array = [MyStruct(value: 1), MyStruct(value: 2), MyStruct(value: 3)]
// Элементы массива могут быть размещены в кучеКогда массив содержит много элементов, память для них может быть выделена в куче для управления их жизненным циклом.
Value типы в Swift могут стать reference, когда они захватываются замыканиями, оборачиваются в классы, являются свойствами классов или хранятся в больших коллекциях. Это необходимо для управления памятью и жизненным циклом данных в более сложных сценариях.
В двух фразах: Value типы в Swift могут храниться в куче, когда захватываются замыканиями, оборачиваются в классы, используются в качестве свойств классов или хранятся в больших коллекциях. Это помогает управлять памятью и жизненным циклом данных в сложных сценариях.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥3👍1
Anonymous Quiz
5%
Codable
18%
Sequence
73%
AsyncSequence
4%
IteratorProtocol
👍2
UIResponder — это базовый класс для объектов, которые могут обрабатывать события в iOS-приложениях, такие как касания, жесты и нажатия клавиш. UIResponder управляет цепочкой ответчиков, передавая события от одного объекта к другому, если текущий объект не может их обработать.Объекты, унаследованные от
UIResponder, могут обрабатывать различные события через методы, такие как touchesBegan, touchesMoved, touchesEnded и touchesCancelled.Определяет, как события передаются между объектами, гарантируя, что все события будут обработаны.
class CustomView: UIView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
print("Touches began")
}
}UIResponder — это ключевой класс для обработки событий в iOS, предоставляющий методы для работы с касаниями и другими взаимодействиями пользователя.В двух фразах:
UIResponder обрабатывает события в iOS и управляет цепочкой ответчиков. Он является базовым классом для таких объектов, как UIView и UIViewController, обеспечивая их способность реагировать на события.Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4
Anonymous Quiz
92%
Замыкания
3%
Протоколы
4%
Делегаты
1%
Модули
❤1
Autorelease pool — это механизм управления памятью в Objective-C и Swift, который помогает автоматизировать освобождение объектов, когда они больше не нужны. Этот механизм используется для временного хранения объектов, которым необходимо отправить сообщение
release в будущем, чтобы освободить их память. Autorelease pool обеспечивает автоматическое управление памятью и предотвращает утечки памяти, особенно в случаях, когда создаётся много временных объектов.release.Objective-C:
@autoreleasepool {
// Создание временных объектов
NSString *tempString = [[NSString alloc] initWithFormat:@"Hello, %@", @"World"];
// tempString автоматически освободится, когда пул спустится
}Swift:
autoreleasepool {
// Создание временных объектов
let tempString = NSString(format: "Hello, %@", "World")
// tempString автоматически освободится, когда пул спустится
}Управление памятью в циклах: При создании большого количества временных объектов внутри цикла autorelease pool предотвращает увеличение использования памяти.
for i in 0..<1000 {
autoreleasepool {
let tempString = NSString(format: "Iteration %d", i)
// tempString освобождается в конце каждой итерации
}
}Автоматическое освобождение объектов: Autorelease pool позволяет избежать явного вызова
release для каждого объекта, предоставляя автоматическое управление памятью.Создание объектов: Когда объект создаётся с использованием методов, которые возвращают autoreleased объект, он добавляется в текущий autorelease pool.
NSString *string = [NSString stringWithFormat:@"Hello, World"];
Спуск пула: Когда пул спускается, всем объектам, находящимся в пуле, отправляется сообщение
release, что приводит к их освобождению, если нет других сильных ссылок на них.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤔2
Anonymous Quiz
20%
Указывает на косвенные ссылки
65%
Позволяет рекурсивные перечисления
7%
Делает перечисление асинхронным
9%
Упрощает сериализацию
👍1
Метод
viewWillAppear вызывается в жизненном цикле UIViewController перед тем, как его представление (view) становится видимым пользователю. Этот метод вызывается каждый раз, когда представление контроллера собирается появиться на экране, даже если оно уже было загружено в память.UIViewControllerЗагрузка представления:
loadView(): Вызывается, когда представление контроллера загружается в память.viewDidLoad(): Вызывается после загрузки представления в память. Используется для первоначальной настройки представления и инициализации данных.Перед появлением на экране:
viewWillAppear(_:): Вызывается непосредственно перед тем, как представление контроллера становится видимым на экране. Это хороший момент для обновления данных и интерфейса, если они могли измениться.Появление на экране:
viewDidAppear(_:): Вызывается после того, как представление контроллера стало видимым на экране. Здесь можно запускать анимации или начинать задачи, которые должны выполняться только после того, как представление полностью отображено.Перед исчезновением с экрана:
viewWillDisappear(_:): Вызывается непосредственно перед тем, как представление контроллера исчезнет с экрана. Это подходящее место для остановки анимаций, сохранения состояния и освобождения ресурсов.Исчезновение с экрана:
viewDidDisappear(_:): Вызывается после того, как представление контроллера исчезло с экрана. Используется для выполнения действий, которые должны произойти после того, как представление перестало быть видимым.class MyViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Обновление интерфейса перед тем, как представление станет видимым
print("viewWillAppear: Представление скоро станет видимым")
// Обновление данных
updateData()
}
func updateData() {
// Логика обновления данных
}
}viewWillAppearСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
Anonymous Quiz
6%
weak
94%
lazy
0%
unowned
0%
deferred
❤1
Управление памятью (Memory Management) в iOS включает использование автоматического подсчета ссылок (ARC) и инструментов Xcode для анализа и профилирования памяти. ARC автоматически управляет памятью, увеличивая и уменьшая счетчик ссылок на объекты. Когда объект больше не имеет сильных ссылок (strong references), он освобождается.
Automatic Reference Counting (ARC)
class Person {
var name: String
weak var spouse: Person?
init(name: String) {
self.name = name
}
}Xcode Instruments
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Anonymous Quiz
41%
Equatable
39%
Comparable
12%
Hashable
7%
CaseIterable
👍1
Очереди (queues) в iOS и macOS используются для управления задачами в многопоточном программировании с помощью Grand Central Dispatch (GCD). Существуют два основных типа очередей: последовательные (serial) и конкурентные (concurrent). Они различаются по способу выполнения задач.
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
print("Task 1")
}
serialQueue.async {
print("Task 2")
}
// Task 1 будет выполнена перед Task 2
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
print("Task 1")
}
concurrentQueue.async {
print("Task 2")
}
// Task 1 и Task 2 могут быть выполнены одновременно
DispatchQueue.main.async {
print("Update UI")
}
// Эта задача будет выполнена на главном потоке DispatchQueue.global(qos: .userInitiated).async {
print("High priority task")
}
DispatchQueue.global(qos: .background).async {
print("Low priority task")
}
// Задачи будут выполнены в соответствии с их приоритетом Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
Anonymous Quiz
8%
as!
85%
as?
4%
as
2%
is?
👍1
Динамическая диспетчеризация в Swift начинает работать, когда методы или свойства вызываются во время выполнения программы (runtime), а не на этапе компиляции. Это может быть связано с различными механизмами, включая использование
@objc и динамических ключевых слов, протоколы с необязательной реализацией, и взаимодействие с Objective-C API. Давайте рассмотрим основные случаи, когда применяется динамическая диспетчеризация:Использование `@objc` и динамических ключевых слов: Методы и свойства, помеченные атрибутом
@objc или ключевым словом dynamic, используют динамическую диспетчеризацию через Objective-C runtime. Это позволяет изменять поведение методов в процессе выполнения, например, через механизм замен (swizzling).import Foundation
class MyClass: NSObject {
@objc dynamic func myMethod() {
print("Original implementation")
}
}
let obj = MyClass()
obj.myMethod() // Вызов через динамическую диспетчеризацию
Протоколы с необязательной реализацией: Протоколы, объявленные с
@objc, могут иметь необязательные методы, которые вызываются через динамическую диспетчеризацию. Это позволяет проверять наличие метода и вызывать его только при наличии.@objc protocol MyProtocol {
@objc optional func optionalMethod()
}
class MyClass: NSObject, MyProtocol {
func optionalMethod() {
print("Optional method implementation")
}
}
let obj: MyProtocol = MyClass()
obj.optionalMethod?() // Вызов через динамическую диспетчеризацию Интерактивное взаимодействие с Objective-C API: Методы, которые взаимодействуют с Objective-C API или наследуются от классов, написанных на Objective-C, используют динамическую диспетчеризацию для вызова методов через Objective-C runtime.
import UIKit
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Этот метод вызывается через динамическую диспетчеризацию
}
}
Преимущества:
Недостатки:
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2
Anonymous Quiz
3%
open
12%
public
58%
internal
27%
private
👍2
В iOS для выполнения фоновых задач существуют несколько ключевых механизмов:
DispatchQueue.global(qos: .background).async {
// Фоновая задача
}let queue = OperationQueue()
queue.addOperation {
// Фоновая операция
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Фоновое обновление данных
completionHandler(.newData)
} import BackgroundTasks
func scheduleBackgroundTask() {
let request = BGAppRefreshTaskRequest(identifier: "com.example.app.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
}
let configuration = URLSessionConfiguration.background(withIdentifier: "com.example.app.background")
let session = URLSession(configuration: configuration)
let url = URL(string: "https://example.com/largefile")!
let task = session.downloadTask(with: url)
task.resume()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Anonymous Quiz
28%
Deep Copy
10%
Shallow Copy
25%
Copy Constructor
38%
Value Semantics
🤔12👾3
actor — это новый тип, введённый в Swift 5.5, который предназначен для упрощения и повышения безопасности многопоточного программирования. actor позволяет инкапсулировать состояние и обеспечивает синхронизацию доступа к этому состоянию, предотвращая состояния гонки (race conditions).Все свойства и методы
actor защищены и могут быть безопасно изменены только внутри самого actor. Внешний доступ к состоянию actor происходит через асинхронные вызовы, обеспечивая безопасную синхронизацию.actor автоматически синхронизирует доступ к своим данным, что исключает состояния гонки и делает код безопасным для многопоточного использования.Вызов методов
actor и доступ к его свойствам извне осуществляется через асинхронные функции с использованием await.Пример использования
actoractor Counter {
private var value = 0
func increment() {
value += 1
}
func getValue() -> Int {
return value
}
}
let counter = Counter()
Task {
await counter.increment()
let value = await counter.getValue()
print("Counter value: \(value)")
}Внутреннее состояние
actor доступно только через методы и свойства самого actor. Прямой доступ к свойствам извне невозможен.Все взаимодействия с
actor из других контекстов требуют использования await, что обеспечивает синхронизацию доступа.Использование
actor упрощает код и делает его более безопасным по сравнению с ручным использованием Grand Central Dispatch (GCD) или мьютексов для синхронизации. actor автоматически управляет синхронизацией, устраняя необходимость в ручном управлении очередями и блокировкамиclass Counter {
private var value = 0
private let queue = DispatchQueue(label: "com.example.counter")
func increment() {
queue.sync {
value += 1
}
}
func getValue() -> Int {
return queue.sync {
return value
}
}
}class Counter {
private var value = 0
private let lock = NSLock()
func increment() {
lock.lock()
value += 1
lock.unlock()
}
func getValue() -> Int {
lock.lock()
let currentValue = value
lock.unlock()
return currentValue
}
}async и await.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4
Anonymous Quiz
17%
fileprivate
44%
private
17%
internal
21%
extension
🤔11🤯3👍1😁1
В Swift структуры являются типами значений (value types), что означает, что они по умолчанию копируются при передаче или присвоении. Однако копирование структуры происходит только при изменении (copy-on-write) её состояния, чтобы оптимизировать производительность и снизить избыточные копии. Рассмотрим подробнее, как это работает.
struct MyStruct {
var value: Int
}
var a = MyStruct(value: 10)
var b = a // Копия создается, но фактически это происходит "лениво"
b.value = 20 // В этот момент происходит копирование, так как структура изменяется
print(a.value) // Output: 10
print(b.value) // Output: 20a создается и инициализируется значением 10.b присваивается значение a. На этом этапе копия не создается, так как копирование структур в Swift оптимизировано и происходит лениво.value структуры b, происходит копирование, чтобы изменить b без изменения a.Это оптимизация, при которой фактическое копирование структуры происходит только тогда, когда необходимо изменить её содержимое. До тех пор, пока структура не изменяется, обе переменные будут ссылаться на одни и те же данные.
struct LargeStruct {
var data = [Int](repeating: 0, count: 1000)
}
var x = LargeStruct()
var y = x // Копия не создается сразу
y.data[0] = 1 // Копирование происходит здесь, при изменении
print(x.data[0]) // Output: 0
print(y.data[0]) // Output: 1x присваивается структура LargeStruct, содержащая массив данных.y присваивается значение x. На этом этапе копия не создается.data в структуре y, происходит копирование данных, чтобы x и y имели свои собственные копии массива.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Anonymous Quiz
15%
Delegation
26%
Adapter
44%
Protocol Extension
16%
Type Erasure
😁4