Это ключевое слово, которое используется для создания неустранимых ссылок. Неустранимая ссылка (
unowned) не увеличивает счётчик ссылок на объект, к которому она относится, и, в отличие от слабых ссылок (weak), не обнуляется автоматически, когда объект освобождается из памяти. Использование unowned ссылок полезно в тех случаях, когда вы уверены, что объект, на который ссылается unowned ссылка, будет существовать на протяжении всей жизни ссылки.Unowned ссылки не удерживают объект в памяти, что предотвращает циклические ссылки.Если объект, на который ссылается
unowned ссылка, освобождается из памяти, попытка доступа к этой ссылке приведёт к ошибке времени выполнения (runtime crash).Unowned ссылки следует использовать только тогда, когда вы уверены, что объект будет существовать на протяжении всей жизни ссылки.class Person {
var name: String
var creditCard: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) is being deinitialized")
}
}
class CreditCard {
var number: Int
unowned var owner: Person
init(number: Int, owner: Person) {
self.number = number
self.owner = owner
}
deinit {
print("CreditCard #\(number) is being deinitialized")
}
}
var john: Person? = Person(name: "John")
john!.creditCard = CreditCard(number: 1234, owner: john!)
john = nil
// Output:
// John is being deinitialized
// CreditCard #1234 is being deinitializedPerson с именем "John".CreditCard, который имеет unowned ссылку owner на john.john освобождается (при присвоении nil), также освобождается и объект CreditCard. Случаи использования unownedВы уверены, что объект будет существовать на протяжении всей жизни ссылки.
unowned позволяет избежать использования опционалов (Optional), что упрощает код.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3
Используется для отображения списков данных и оптимизирует производительность с помощью повторного использования ячеек.
tableView(_:numberOfRowsInSection:): Количество строк.tableView(_:cellForRowAt:): Конфигурация ячеек.tableView(_:didSelectRowAt:): Обработка выбора строки.tableView(_:heightForRowAt:): Настройка высоты строки.Ячейки (
UITableViewCell) отображают контент.Добавьте
UITableView в ViewController через Interface Builder или программно. Подключите UITableView как IBOutlet.Назначьте
ViewController источником данных и делегатом таблицы. Реализуйте методы протоколов. import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1000 // Количество строк
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "Row \(indexPath.row)"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Selected row: \(indexPath.row)")
}
}
Используйте
dequeueReusableCell(withIdentifier:for:) для повторного использования ячеек.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
1. `loadView` создает представление, которое контроллер управляет.
2. `viewDidLoad` вызывается после загрузки представления контроллера в память.
3. `viewWillAppear` выполняется перед тем, как представление станет видимым.
4. `viewDidAppear` вызывается после того, как представление появилось на экране.
5. `viewWillDisappear` и `viewDidDisappear` вызываются перед и после того, как представление было удалено с экрана.
6. `deinit` вызывается перед освобождением экземпляра контроллера из памяти.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Модель представляет данные и бизнес-логику, представление отвечает за отображение данных и взаимодействие с пользователем, а ViewModel связывает модель и представление, управляя состоянием и логикой представления.
- Models
- User.swift
- Views
- UserView.swift
- ViewModels
- UserViewModel.swift
Модель представляет данные и бизнес-логику. Например, это может быть структура
User. struct User {
let name: String
let age: Int
}ViewModel связывает модель и представление, управляя состоянием и логикой представления. Он использует
@Published для обновления представления при изменении данных. import Combine
class UserViewModel: ObservableObject {
@Published var user: User?
func fetchUser() {
// Логика получения данных пользователя (например, из сети или базы данных)
self.user = User(name: "John Doe", age: 30)
}
}
Представление отвечает за отображение данных и взаимодействие с пользователем. В SwiftUI представление использует
@StateObject или @ObservedObject для наблюдения за изменениями данных в ViewModel. import SwiftUI
struct UserView: View {
@StateObject var viewModel = UserViewModel()
var body: some View {
VStack {
if let user = viewModel.user {
Text("Name: \(user.name)")
Text("Age: \(user.age)")
} else {
Text("Loading...")
}
}
.onAppear {
viewModel.fetchUser()
}
}
}
struct UserView_Previews: PreviewProvider {
static var previews: some View {
UserView()
}
}
User.swift
struct User {
let name: String
let age: Int
}UserViewModel.swift
import Combine
class UserViewModel: ObservableObject {
@Published var user: User?
func fetchUser() {
// Логика получения данных пользователя (например, из сети или базы данных)
self.user = User(name: "John Doe", age: 30)
}
}
UserView.swift
import SwiftUI
struct UserView: View {
@StateObject var viewModel = UserViewModel()
var body: some View {
VStack {
if let user = viewModel.user {
Text("Name: \(user.name)")
Text("Age: \(user.age)")
} else {
Text("Loading...")
}
}
.onAppear {
viewModel.fetchUser()
}
}
}
struct UserView_Previews: PreviewProvider {
static var previews: some View {
UserView()
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Расшифровывается как Core Animation. Это фреймворк, используемый в iOS и macOS для создания анимаций. Core Animation предоставляет высокоуровневый API для работы с анимациями, которые могут быть применены к слоям (CALayer). Он позволяет разработчикам создавать плавные и эффективные анимации с минимальными усилиями.
Анимация изменения свойств слоя, таких как позиция, масштаб, поворот, прозрачность и т.д.
Создание сложных анимаций с использованием ключевых кадров, позволяющих анимировать свойства слоя по нескольким значениям.
Одновременное выполнение нескольких анимаций, объединенных в одну группу.
Анимация переходов между состояниями слоев, таких как изменение содержимого или структуры слоя.
Core Animation основывается на слоях (CALayer), которые представляют собой абстракцию для управления графическим содержимым и анимациями.
Основная анимация (CABasicAnimation)
import UIKit
class AnimationViewController: UIViewController {
let animatedLayer = CALayer()
override func viewDidLoad() {
super.viewDidLoad()
// Настройка слоя
animatedLayer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
animatedLayer.backgroundColor = UIColor.blue.cgColor
self.view.layer.addSublayer(animatedLayer)
// Создание анимации перемещения
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = CGPoint(x: 50, y: 50)
animation.toValue = CGPoint(x: 300, y: 300)
animation.duration = 2.0
// Добавление анимации к слою
animatedLayer.add(animation, forKey: "positionAnimation")
// Обновление конечного состояния слоя
animatedLayer.position = CGPoint(x: 300, y: 300)
}
}
CAKeyframeAnimation
import UIKit
class KeyframeAnimationViewController: UIViewController {
let animatedLayer = CALayer()
override func viewDidLoad() {
super.viewDidLoad()
// Настройка слоя
animatedLayer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
animatedLayer.backgroundColor = UIColor.red.cgColor
self.view.layer.addSublayer(animatedLayer)
// Создание анимации ключевых кадров
let keyframeAnimation = CAKeyframeAnimation(keyPath: "position")
keyframeAnimation.values = [
CGPoint(x: 50, y: 50),
CGPoint(x: 150, y: 150),
CGPoint(x: 250, y: 50),
CGPoint(x: 300, y: 300)
]
keyframeAnimation.duration = 4.0
// Добавление анимации к слою
animatedLayer.add(keyframeAnimation, forKey: "positionKeyframeAnimation")
// Обновление конечного состояния слоя
animatedLayer.position = CGPoint(x: 300, y: 300)
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3😁1
Это высокоуровневый механизм синхронизации, который объединяет взаимное исключение (mutex) и условные переменные (condition variables) для управления доступом к объектам в многопоточной среде.
Только один поток может выполнить защищенный блок кода в любой момент времени.
Позволяют потокам ожидать определенных условий, а другим потокам уведомлять их о наступлении этих условий.
class ThreadSafeClass {
private var internalState = 0
private let queue = DispatchQueue(label: "com.example.threadSafeQueue")
func increment() {
queue.sync {
internalState += 1
}
}
func getState() -> Int {
return queue.sync {
internalState
}
}
}С
NSLockclass ThreadSafeClass {
private var internalState = 0
private let lock = NSLock()
func increment() {
lock.lock()
internalState += 1
lock.unlock()
}
func getState() -> Int {
lock.lock()
let state = internalState
lock.unlock()
return state
}
}С
objc_sync_enter и objc_sync_exitclass ThreadSafeClass: NSObject {
private var internalState = 0
func increment() {
objc_sync_enter(self)
internalState += 1
objc_sync_exit(self)
}
func getState() -> Int {
objc_sync_enter(self)
let state = internalState
objc_sync_exit(self)
return state
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3
В отличие от некоторых других языков, таких как Java, нет прямого способа "повесить" синхронизацию на отдельную переменную с использованием ключевого слова
synchronized. Вместо этого, синхронизация осуществляется на уровне методов или блоков кода, которые обращаются к переменной. Это достигается использованием механизмов синхронизации, таких как NSLock, DispatchQueue, или атомарные переменные.В данном примере, доступ к переменной
_value синхронизирован с помощью NSLock, что предотвращает одновременное чтение и запись из нескольких потоков.class ThreadSafeVariable {
private var _value: Int = 0
private let lock = NSLock()
var value: Int {
get {
lock.lock()
let v = _value
lock.unlock()
return v
}
set {
lock.lock()
_value = newValue
lock.unlock()
}
}
}В этом примере, доступ к переменной
_value осуществляется через серийную очередь, что обеспечивает эксклюзивный доступ к переменной в любой момент времени.class ThreadSafeVariable {
private var _value: Int = 0
private let queue = DispatchQueue(label: "com.example.threadSafeQueue")
var value: Int {
get {
return queue.sync {
_value
}
}
set {
queue.sync {
_value = newValue
}
}
}
}Здесь используется атомарная переменная
ManagedAtomic для обеспечения безопасного доступа к переменной _value.import Atomics
class ThreadSafeVariable {
private var _value = ManagedAtomic(0)
var value: Int {
get {
return _value.load(ordering: .relaxed)
}
set {
_value.store(newValue, ordering: .relaxed)
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Это базовое понятие в объектно-ориентированном программировании (ООП). Это экземпляр класса, который может содержать данные и методы для работы с этими данными. В Swift, как и в большинстве ООП-языков, объекты играют ключевую роль в организации и структурировании кода.
Представлено данными или свойствами (properties) объекта. Например, объект
Car может иметь свойства color, model, и year.Определяется методами (methods) объекта. Например, объект
Car может иметь методы drive() и brake().Каждый объект имеет уникальную идентичность, которая отличает его от других объектов, даже если их состояния идентичны.
Это шаблон или чертеж для создания объектов. Он определяет свойства и методы, которые будут у объектов данного класса. Объект является экземпляром класса.
class Car {
var color: String
var model: String
var year: Int
init(color: String, model: String, year: Int) {
self.color = color
self.model = model
self.year = year
}
func drive() {
print("The \(color) \(model) is driving.")
}
func brake() {
print("The \(color) \(model) is braking.")
}
}Создание объекта:
let myCar = Car(color: "Red", model: "Toyota", year: 2020)
myCar.drive()
myCar.brake()
Объекты скрывают детали реализации и предоставляют интерфейс для взаимодействия. Это способствует защите данных и улучшению модульности.
Объекты могут наследовать свойства и методы от других классов, позволяя создавать иерархии классов и повторно использовать код.
Объекты могут быть обработаны через интерфейсы или базовые классы, что позволяет использовать один и тот же код для объектов разных типов.
В этом примере, свойство
age скрыто от внешнего доступа, и доступ к нему осуществляется через методы getAge и setAge.class Person {
private var age: Int
init(age: Int) {
self.age = age
}
func getAge() -> Int {
return age
}
func setAge(newAge: Int) {
if newAge > 0 {
age = newAge
}
}
}
let person = Person(age: 25)
print(person.getAge()) // 25
person.setAge(newAge: 30)
print(person.getAge()) // 30Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
1. Инкапсуляция: сокрытие внутренних деталей реализации объекта и объединение данных и методов, работающих с этими данными, в один объект.
2. Наследование: создание нового класса на основе существующего.
3. Полиморфизм: возможность обращаться с объектами, производными от одного базового класса, для выполнения методов, определенных в базовом классе, но переопределенных в производных.
4. Абстракция: определение интерфейса взаимодействия с объектом, отделяющего его функциональное поведение от конкретной реализации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Объект создается в момент инициализации экземпляра класса. В языке Swift это происходит при вызове конструктора (initializer) класса с использованием ключевого слова
init. Когда инициализатор вызывается, выделяется память для объекта, и его свойства устанавливаются значениями, указанными в инициализаторе.Память для нового объекта выделяется в heap (куче).
Все свойства объекта инициализируются значениями, указанными в конструкторе.
Конструктор устанавливает начальное состояние объекта.
class Car {
var color: String
var model: String
var year: Int
init(color: String, model: String, year: Int) {
self.color = color
self.model = model
self.year = year
}
func drive() {
print("The \(color) \(model) is driving.")
}
func brake() {
print("The \(color) \(model) is braking.")
}
}let myCar = Car(color: "Red", model: "Toyota", year: 2020)
Память для объекта
myCar выделяется в heap.Свойства
color, model и year инициализируются значениями "Red", "Toyota" и 2020 соответственно.Инициализатор
init(color:model:year:) устанавливает эти значения.Основные инициализаторы, которые инициализируют все свойства объекта.
Вспомогательные инициализаторы, которые вызывают другой инициализатор и могут задавать дополнительные параметры.
class Car {
var color: String
var model: String
var year: Int
init(color: String, model: String, year: Int) {
self.color = color
self.model = model
self.year = year
}
convenience init(model: String) {
self.init(color: "White", model: model, year: 2020)
}
}
let defaultCar = Car(model: "Honda")Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3
Forwarded from Идущий к IT
Твое резюме на HeadHunter — ОК, если ты видишь это.
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
В языках программирования, таких как Kotlin, термин
companion object используется для обозначения особого объекта, который связан с определенным классом и позволяет хранить статические члены этого класса. В Swift нет прямого аналога companion object, но схожие концепции можно реализовать с помощью статических свойств и методов.Используется для определения статических членов класса. Они могут быть вызваны без создания экземпляра класса.
class MyClass {
companion object {
fun staticMethod() {
println("This is a static method")
}
}
}
// Вызов метода без создания экземпляра класса
MyClass.staticMethod()В Swift статические члены класса (свойства и методы) определяются с использованием ключевого слова
static. Статические члены принадлежат самому классу, а не его экземплярам.class MyClass {
static func staticMethod() {
print("This is a static method")
}
}
// Вызов метода без создания экземпляра класса
MyClass.staticMethod()Также можно использовать ключевое слово
class для определения методов класса, которые могут быть переопределены в подклассах. class MyClass {
class func classMethod() {
print("This is a class method")
}
}
class SubClass: MyClass {
override class func classMethod() {
print("This is an overridden class method")
}
}
// Вызов метода без создания экземпляра класса
MyClass.classMethod() // Output: This is a class method
SubClass.classMethod() // Output: This is an overridden class methodСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Когда вы добавляете обычный объект внутри класса, вы создаете именованный объект, который является экземпляром анонимного класса. Он может содержать свойства и методы, и он создается один раз при создании экземпляра внешнего класса.
class MyClass {
let instanceProperty = "Instance Property"
struct MyObject {
static let objectProperty = "Object Property"
static func objectMethod() {
print("This is an object method")
}
}
}
// Использование
let myClassInstance = MyClass()
print(MyClass.MyObject.objectProperty) // Доступ к свойствам и методам объекта через имя объекта
MyClass.MyObject.objectMethod()Companion Object (компаньон-объект)
Companion object позволяет определить статические члены класса. Эти члены доступны без создания экземпляра класса. Вы можете использовать companion object для хранения статических методов и свойств, которые могут быть вызваны напрямую через имя класса. class MyClass {
let instanceProperty = "Instance Property"
companion object {
let companionProperty = "Companion Property"
func companionMethod() {
print("This is a companion object method")
}
}
}
// ИспользованиеОбычный объект: Доступ к свойствам и методам обычного объекта осуществляется через его имя. Companion Object: Доступ к свойствам и методам компаньон-объекта осуществляется через имя класса.
Обычный объект: Не привязан к конкретному экземпляру класса и создается один раз для всего класса. Companion Object: Также не привязан к конкретному экземпляру класса и создается один раз для всего класса, но служит для определения статических членов класса.
Обычный объект: Требует явного имени для доступа. Companion Object: Имеет неявное имя Companion, если не указано другое имя. Это позволяет получить доступ к его членам без явного указания имени.
class MyClass {
val instanceProperty = "Instance Property"
object MyObject {
val objectProperty = "Object Property"
fun objectMethod() {
println("This is an object method")
}
}
companion object {
val companionProperty = "Companion Property"
fun companionMethod() {
println("This is a companion object method")
}
}
}
// Доступ к свойствам и методам объекта через имя объекта
println(MyClass.MyObject.objectProperty)
MyClass.MyObject.objectMethod()
// Доступ к свойствам и методам компаньон-объекта через имя класса
println(MyClass.companionProperty)
MyClass.companionMethod()Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯2