Sitable появляется в качестве новой функции, когда объект или пространство становится подходящим для использования. Это происходит благодаря изменению условий, которые делают его удобным или доступным. Например, помещение может стать sitable после установки мебели или проведения ремонта.
Файл с отладочной информацией для декодирования отчетов о сбоях. Он связывает машинный код с исходным кодом.
Имена методов и классов.
Декодирование отчетов о сбоях.
Пример:
Взаимозаменяемое использование объектов Core Foundation и Foundation в Swift и Objective-C без преобразования.
Связь: Использование объектов Core Foundation и Foundation.
Примеры:
CFStringRef и NSStringCFArrayRef и NSArrayCFDictionaryRef и NSDictionaryUITableView
let tableView = UITableView()
tableView.dataSource = self
UICollectionView
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.dataSource = self
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Wick-ссылки являются прямыми и предотвращают удаление объекта сборщиком мусора, тогда как Anound-ссылки являются слабыми и позволяют сборщику мусора удалить объект при отсутствии других прямых ссылок.
Слабая ссылка не удерживает объект в памяти. Объект может быть освобожден, если на него нет других сильных ссылок. Может быть nil. Используется с
Optional типами. Автоматически становится nil, когда объект освобождается. Для объектов, которые могут исчезнуть во время жизненного цикла.class Person {
var name: String
weak var friend: Person?
init(name: String) {
self.name = name
}
}
var alice: Person? = Person(name: "Alice")
var bob: Person? = Person(name: "Bob")
alice?.friend = bob
bob?.friend = alice Неактивная ссылка не удерживает объект в памяти и не может быть nil. Никогда не бывает nil. Используется с
non-Optional типами. Программа крашнется при попытке доступа к освобожденному объекту. Для объектов, которые должны существовать на протяжении всего жизненного цикла другого объекта.class Person {
var name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
}
class Apartment {
unowned var tenant: Person
init(tenant: Person) {
self.tenant = tenant
}
}
var alice: Person? = Person(name: "Alice")
var apt = Apartment(tenant: alice!) Weak: Может быть nil.
Unowned: Никогда не бывает nil.
Weak: Используется, когда объект может быть освобожден во время жизненного цикла.
Unowned: Используется, когда объект должен существовать столько же, сколько и его владелец.
Weak: Для делегатов и объектов, которые могут исчезнуть.
Unowned: Для циклических зависимостей, где один объект гарантированно существует.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
В Swift объекты классов и структуры имеют различия в управлении памятью и способе обращения.
Являются ссылочными типами, что означает, что объекты классов передаются по ссылке.
Создание
class Person {
var name: String
init(name: String) {
self.name = name
}
}
let person1 = Person(name: "Alice")
let person2 = person1 // person2 указывает на тот же объект, что и person1 Изменение свойств
person2.name = "Bob"
print(person1.name) // "Bob"
Являются значимыми типами, что означает, что объекты структур передаются по значению.
Создание
struct Person {
var name: String
}
var person1 = Person(name: "Alice")
var person2 = person1 // person2 является копией person1Изменение свойств
person2.name = "Bob"
print(person1.name) // "Alice"
Классы передаются по ссылке. Изменения через одну ссылку отражаются на всех ссылках.
Структуры передаются по значению. Каждое присваивание или передача создает копию.
Классы: Используются для объектов, которым требуется идентичность или наследование.
Структуры: Используются для простых данных, которые логически являются значениями, таких как точки, размеры или пользовательские данные.
Классы
class Car {
var model: String
init(model: String) {
self.model = model
}
}
let car1 = Car(model: "Tesla")
let car2 = car1
car2.model = "BMW"
print(car1.model) // "BMW"Структуры
struct Car {
var model: String
}
var car1 = Car(model: "Tesla")
var car2 = car1
car2.model = "BMW"
print(car1.model) // "Tesla"Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это концепции, которые используются для поддержки полиморфизма и динамического диспетчеризации методов.
Это структура данных, используемая компилятором Swift для обеспечения полиморфизма при работе с протоколами. Она содержит указатели на функции, реализующие требования протокола для конкретного типа. Это позволяет динамически вызывать методы протокола на объекте, даже если точный тип объекта неизвестен.
Протоколы определяют интерфейс (набор методов и свойств), который должен быть реализован типом. Когда тип соответствует протоколу, компилятор создает таблицу свидетельств для этого типа.
Таблица свидетельств содержит указатели на реализации методов и свойств, определенных в протоколе. При вызове метода протокола через объект типа, соответствующего протоколу, используется таблица свидетельств для динамического поиска и вызова правильного метода.
Swift использует таблицы свидетельств для реализации динамического полиморфизма, позволяя вызывать методы протокола на объектах различных типов. Это обеспечивает гибкость и расширяемость кода.
Определение протокола и соответствующего типа
protocol Drawable {
func draw()
}
class Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}
class Square: Drawable {
func draw() {
print("Drawing a square")
}
}
func render(shape: Drawable) {
shape.draw() // Использование таблицы свидетельств для вызова правильного метода draw()
}
let shapes: [Drawable] = [Circle(), Square()]
for shape in shapes {
render(shape: shape)
}Таблицы свидетельств позволяют Swift поддерживать полиморфизм через протоколы.
Они обеспечивают динамическую диспетчеризацию методов, что позволяет вызывать методы на объектах различных типов, соответствующих одному протоколу.
Использование таблиц свидетельств позволяет оптимизировать вызовы методов и улучшить производительность по сравнению с другими методами динамической диспетчеризации.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это упорядоченная коллекция элементов одного типа. Массивы являются одним из основных и наиболее часто используемых типов данных в Swift. Они предоставляют множество методов и свойств для управления и обработки коллекций данных.
Пустой массив
var emptyArray: [Int] = []
var anotherEmptyArray = [Int]()
Массив с начальными значениями
var numbers: [Int] = [1, 2, 3, 4, 5]
var moreNumbers = [1, 2, 3, 4, 5]
По индексу
let firstNumber = numbers[0] // 1
Изменение элемента
numbers[0] = 10 // теперь numbers = [10, 2, 3, 4, 5]
В конец массива
numbers.append(6) // теперь numbers = [10, 2, 3, 4, 5, 6]
Вставка по индексу
numbers.insert(7, at: 1) // теперь numbers = [10, 7, 2, 3, 4, 5, 6]
По индексу
numbers.remove(at: 1) // теперь numbers = [10, 2, 3, 4, 5, 6]
Последний элемент
numbers.removeLast() // теперь numbers = [10, 2, 3, 4, 5]
Все элементы
numbers.removeAll() // теперь numbers = []
С использованием цикла
forfor number in numbers {
print(number)
} С использованием метода
forEachnumbers.forEach { print($0) } Фильтрация
let evenNumbers = numbers.filter { $0 % 2 == 0 } Преобразование
let stringNumbers = numbers.map { String($0) }
let sum = numbers.reduce(0, +)
Элементы хранятся в определенном порядке и доступ к ним возможен по индексу.
Легко добавлять и удалять элементы, изменять их порядок.
Массивы предоставляют множество методов для обработки данных, таких как фильтрация, сортировка, преобразование и т.д.
Все элементы массива должны быть одного типа, что обеспечивает безопасность типов.
Доступ по индексу выполняется за постоянное время O(1), но вставка и удаление элементов могут иметь сложность O(n), если они происходят не в конце массива.
Если массив объявлен с использованием
let, он становится неизменяемым, и его элементы нельзя добавлять или удалять. let immutableNumbers = [1, 2, 3]
// immutableNumbers.append(4) // Ошибка: Невозможно изменить неизменяемый массив
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Это механизм в iOS и macOS для обмена сообщениями между различными частями приложения. Он позволяет объектам отправлять и получать уведомления без необходимости напрямую ссылаться друг на друга, что способствует более гибкому и модульному дизайну.
Любой объект может отправить уведомление с помощью Notification Center. Уведомления идентифицируются по имени (
Notification.Name). Можно передать дополнительную информацию в виде словаря (userInfo).NotificationCenter.default.post(name: .myNotification, object: nil)
Объекты могут регистрироваться для получения уведомлений с определенным именем. Для обработки уведомлений используется метод, который будет вызван при получении уведомления.
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: .myNotification, object: nil)
@objc func handleNotification(notification: Notification) {
print("Received notification")
}
Важно удалять наблюдателей, когда они больше не нужны, чтобы избежать утечек памяти. Обычно это делается в методе
deinit или перед уничтожением объекта.NotificationCenter.default.removeObserver(self, name: .myNotification, object: nil)
Объекты не нужно напрямую ссылаться друг на друга, что улучшает модульность кода.
Позволяет легко организовать обмен сообщениями между различными частями приложения.
Уведомления могут использоваться многими объектами, что облегчает реализацию функций, таких как обновление интерфейса или реагирование на события.
Когда данные изменяются, можно отправить уведомление для обновления пользовательского интерфейса.
NotificationCenter.default.post(name: .dataDidUpdate, object: nil)
Например, можно подписаться на уведомление о смене состояния сети.
NotificationCenter.default.addObserver(self, selector: #selector(handleNetworkChange), name: .reachabilityChanged, object: nil)
Различные модули приложения могут общаться друг с другом через Notification Center, не создавая сильных зависимостей.
NotificationCenter.default.post(name: .userDidLogin, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUI), name: .userDidLogin, object: nil)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Метод
loadView() в UIViewController отвечает за создание и инициализацию основного представления (view) контроллера. Обычно этот метод используется в специфических случаях, когда требуется полное управление процессом создания представления. Когда необходимо создать и настроить представление программно без использования Interface Builder (storyboards или xibs).
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.text = "Hello, World!"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
self.view = view
} Когда требуется экономить память, загружая представление только при его необходимости, а не при инициализации контроллера. Этот подход позволяет уменьшить использование памяти, особенно в случае сложных или тяжелых представлений.
Когда интерфейс зависит от динамических данных или состояния, доступного только в рантайме. Например, создание различных представлений в зависимости от конфигурации, полученной из сети или другого источника.
Когда требуется специфическая настройка представления, которая не может быть выполнена через Interface Builder. Например, создание представлений с использованием сторонних библиотек или компонентов, которые требуют программного конфигурирования.
В методе
loadView() обязательно должно быть присвоено значение свойству self.view, иначе возникнет ошибка и контроллер не будет иметь основного представления. override func loadView() {
self.view = UIView()
} Рекомендуется минимизировать количество кода в
loadView(), переместив дополнительную настройку представления в метод viewDidLoad() или другие соответствующие методы жизненного цикла.Не выполняйте ресурсоемкие операции в
loadView(), чтобы не замедлять создание представления. Это может негативно повлиять на производительность.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Минимальная логика и количество экранов. Одностраничные приложения. Быстрая разработка.
Быстрое создание прототипов. Демонстрация идей заказчику. Легкость реализации.
Приложения с простой функциональностью. Калькуляторы, справочники. Простота поддержки.
Изучение основ iOS-разработки. Учебные проекты. Понятность для новичков.
Работа с существующими проектами на MVC. Доработка старого кода. Сохранение целостности архитектуры.
Данные и бизнес-логика.
struct User {
let name: String
} Отображение данных (Storyboards, xibs).
@IBOutlet weak var nameLabel: UILabel!
Управление взаимодействием между Model и View.
class ViewController: UIViewController {
var user: User?
override func viewDidLoad() {
super.viewDidLoad()
user = User(name: "Alice")
updateView()
}
func updateView() {
nameLabel.text = user?.name
}
} Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Это классификация различных видов данных, которые могут быть использованы и манипулированы в программе. Они определяют, какие операции можно выполнять с данными и как они хранятся в памяти.
Представляют целые числа.
Int, UInlet age: Int = 25
Представляют дробные числа.
Float, Doublelet pi: Double = 3.14159
Представляют логические значения
true или false. Boollet isActive: Bool = true
Представляют отдельные символы.
Characterlet letter: Character = "A"
Представляют последовательности символов.
Stringlet greeting: String = "Hello, World!"
Представляют упорядоченные коллекции элементов одного типа.
Array<T>let numbers: [Int] = [1, 2, 3, 4, 5]
Представляют коллекции пар ключ-значение.
Dictionary<Key, Value>let user: [String: String] = ["name": "Alice", "age": "30"]
Представляют коллекции уникальных элементов.
Set<T>let uniqueNumbers: Set<Int> = [1, 2, 3, 4, 5]
Представляют тип данных с набором связанных значений.
enum enum CompassPoint {
case north
case south
case east
case west
}
Представляют группы связанных значений.
struct struct Person {
var name: String
var age: Int
}
let person = Person(name: "Alice", age: 30)
Представляют объекты с состоянием и поведением.
class class Car {
var model: String
var year: Int
init(model: String, year: Int) {
self.model = model
self.year = year
}
}
let car = Car(model: "Tesla", year: 2021)
Представляют группы нескольких значений различных типов.
(Type1, Type2, ...)let coordinates: (Int, Int) = (10, 20)
Представляют значение, которое может быть либо некоторым значением, либо nil.
Optional<T>var optionalName: String? = "Alice"
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Anonymous Quiz
18%
?
1%
!
81%
??
0%
&&
Классы и структуры имеют множество общих характеристик, но также имеют ключевые различия, которые определяют их использование в различных ситуациях.
Классы: Ссылочный тип.
Структуры: Значимый тип.
Классы: Передаются по ссылке. При присваивании переменной другого объекта, оба объекта указывают на одну и ту же область памяти.
Структуры: Передаются по значению. При присваивании переменной другой структуры, создается копия структуры.
// Класс
class PersonClass {
var name: String
init(name: String) {
self.name = name
}
}
let person1 = PersonClass(name: "Alice")
let person2 = person1
person2.name = "Bob"
print(person1.name) // "Bob" (оба объекта указывают на одну и ту же память)
// Структура
struct PersonStruct {
var name: String
}
var person3 = PersonStruct(name: "Alice")
var person4 = person3
person4.name = "Bob"
print(person3.name) // "Alice" (создана копия структуры)
Классы: Поддерживают наследование, то есть один класс может наследовать свойства и методы другого класса.
Структуры: Не поддерживают наследование.
// Класс с наследованием
class Vehicle {
var speed: Int = 0
func description() -> String {
return "Moving at \(speed) km/h"
}
}
class Car: Vehicle {
var hasSunroof: Bool = false
}
let myCar = Car()
myCar.speed = 120
myCar.hasSunroof = true
print(myCar.description()) // "Moving at 120 km/h"
Классы: Могут иметь деинициализаторы (deinitializers), которые вызываются перед освобождением экземпляра класса.
Структуры: Не имеют деинициализаторов.
class MyClass {
deinit {
print("MyClass is being deinitialized")
}
}
Классы: Используют автоматическое управление памятью с подсчетом ссылок (ARC). Объекты удаляются, когда на них больше нет сильных ссылок.
Структуры: Удаляются автоматически, когда выходят из области видимости.
Оба: Поддерживают расширения (extensions), что позволяет добавлять новые функциональности к существующим классам или структурам.
Оба: Поддерживают соответствие протоколам.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
Структуры в Swift являются значимыми типами, что означает, что они передаются и копируются по значению. Это означает, что каждая копия структуры является независимой от других копий.
Когда вы присваиваете одну структуру другой или передаете структуру функции, создается копия всей структуры, а не передается ссылка на исходную структуру.
struct Person {
var name: String
var age: Int
}
var person1 = Person(name: "Alice", age: 30)
var person2 = person1 // Создается копия person1
person2.name = "Bob"
print(person1.name) // "Alice" (оригинал не изменился)
print(person2.name) // "Bob" (копия изменена)
Копирование происходит автоматически при присваивании или передаче структур. Это делает работу со структурами безопасной и предсказуемой.
func updateName(person: Person) -> Person {
var updatedPerson = person
updatedPerson.name = "Charlie"
return updatedPerson
}
let person = Person(name: "Alice", age: 30)
let updatedPerson = updateName(person: person)
print(person.name) // "Alice"
print(updatedPerson.name) // "Charlie"
Изменения, сделанные в одной копии структуры, не влияют на другие копии.
var person1 = Person(name: "Alice", age: 30)
var person2 = person1
person2.age = 35
print(person1.age) // 30
print(person2.age) // 35
При копировании структуры копируются также все ее вложенные структуры.
struct Address {
var city: String
}
struct Person {
var name: String
var address: Address
}
var person1 = Person(name: "Alice", address: Address(city: "New York"))
var person2 = person1
person2.address.city = "San Francisco"
print(person1.address.city) // "New York"
print(person2.address.city) // "San Francisco"
Swift использует оптимизацию copy-on-write для некоторых стандартных типов данных (например, массивов). Это означает, что фактическое копирование происходит только тогда, когда одна из копий изменяется.
var array1 = [1, 2, 3]
var array2 = array1 // array1 и array2 указывают на один и тот же массив
array2.append(4) // array2 создает свою копию и модифицирует ее
print(array1) // [1, 2, 3]
print(array2) // [1, 2, 3, 4]
Swift оптимизирует доступ к структурам, чтобы минимизировать издержки на копирование, особенно для больших структур.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1