Swift Apple-ning dasturlash tili bo'lib, Objective-C kuchini zamonaviy tillar xavfsizligi bilan birlashtiradi. Boshqa ko'plab tillardan farqli o'laroq, Swift noyob konstruksiyalarni taklif etadi: avtomatik nusxalash bilan qiymat turlari, kompilyator darajasidagi izolyatsiya bilan Actors, xususiyat mantiqini qayta ishlatish uchun Property Wrappers va klassik meros olish o'rniga Protokolga Yo'naltirilgan Dasturlash.Apple Swift hujjatlari'ga ko'ra, bu xususiyatlar kodni xavfsizroq va samaraliroq qiladi.
Asosiy Nuqtalar
Swift-da struct qiymat turi, class esa mos yozuvlar turidir. Bu asosiy farq tayinlash, funksiyalarga uzatish va xotira boshqaruvi vaqtida xatti-harakatni belgilaydi. Struct har bir tayinlashda to'liq nusxalanadi, class mos yozuv orqali uzatiladi — faqat heap-dagi obyektga ko'rsatgich nusxalanadi.
Struct avtomatik ravishda qiymat semantikasini amalga oshiradi — har bir nusxa mustaqil. Struct xususiyatini o'zgartirish faqat var orqali mumkin va xususiyatlarni o'zgartiruvchi metodlar mutating deb belgilanishi kerak. Struct meros olishni qo'llab-quvvatlamaydi, lekin protokollarga moslasha oladi. Swift standart kutubxonasi String, Array, Dictionary, Int, Bool uchun struct dan foydalanadi — barcha asosiy turlar qiymat turlaridir.
struct User {
let id: Int
var name: String
mutating func updateName(_ newName: String) {
name = newName
}
}
var user1 = User(id: 1, name: "Alice")
var user2 = user1
user2.updateName("Bob")
// user1.name === "Alice", user2.name === "Bob"
// To'liq nusxa — mustaqil nusxalar
Class heap-da saqlanadi va mos yozuv tengligini qo'llab-quvvatlaydi. Bir nechta o'zgaruvchilar bir xil obyektga mos yozuv bo'lishi mumkin, bir mos yozuv orqali o'zgarishlar barcha boshqalarda ko'rinadi. Class meros olishni qo'llab-quvvatlaydi, metodlarni override qilishga imkon beradi, resurslarni tozalash uchun deinit ga ega. Swift-da class struct ga qaraganda kamroq ishlatiladi — Apple struct bilan boshlashni va faqat meros olish yoki mos yozuv semantikasi kerak bo'lganda class ga o'tishni tavsiya qiladi.
class Car {
let model: String
var speed: Int
init(model: String, speed: Int) {
self.model = model
self.speed = speed
}
func accelerate(_ amount: Int) {
speed += amount
}
}
let car1 = Car(model: "Tesla", speed: 0)
let car2 = car1
car2.accelerate(50)
// car1.speed === 50, car2.speed === 50
// Bir xil mos yozuv — o'zgarishlar hamma joyda ko'rinadi
Struct va class o'rtasidagi tanlov ma'lumotlar semantikasiga bog'liq. Konfiguratsiyalar, ma'lumotlar modellari va holatlar uchun struct dan foydalaning — nusxalash xavfsizroq va bashorat qilish osonroq. Identifikatsiyaga ega obyektlar (foydalanuvchi sessiyasi, ma'lumotlar bazasi ulanishi) va meros olish kerak bo'lganda class dan foydalaning.
Actor o'zgaruvchan holatini bir vaqtda kirishdan himoya qiluvchi mos yozuv turidir. Swift kompilyatori actor o'zgaruvchilariga faqat bir xil actor kontekstidan kirish mumkinligini kafolatlaydi — har qanday tashqi kirish kompilyatsiya xatosiga olib keladi. Bu qo'lda blokirovkalarsiz til darajasida ma'lumotlar poygasining oldini oladi.
Barcha actor xususiyatlari va metodlari sukut bo'yicha izolyatsiya qilingan. Tashqaridan actor metodini chaqirish await talab qiladi — Swift bajarishni actor ga o'tkazadi va qaytaradi. Actor kirishni ketma-ket sinxronlashtiradi: turli vazifalardan so'rovlar navbatga qo'yiladi. Bu actor ichida izchil holatni kafolatlaydi. Izolyatsiya qilinmagan metodlar (nonisolated) await siz chaqirilishi mumkin, lekin o'zgaruvchan xususiyatlarga kira olmaydi.
actor BankAccount {
private var balance: Double
init(initialBalance: Double) {
balance = initialBalance
}
func deposit(amount: Double) {
balance += amount
}
func withdraw(amount: Double) throws {
guard balance >= amount else {
throw BankError.insufficientFunds
}
balance -= amount
}
nonisolated func accountInfo() -> String {
return "Bank hisobi"
}
}
let account = BankAccount(initialBalance: 1000)
await account.deposit(amount: 500)
// balance = 1500 — atomik, poyga holatisiz
Actor holat menejerlari, keshlar va tarmoq xizmatlari uchun foydali bo'lib, bu yerda bir nechta vazifalar bir vaqtda ma'lumotlarni o'qiydi va yozadi. NSLock yoki DispatchQueue orqali qo'lda sinxronizatsiyadan farqli o'laroq, actor kompilyatsiya vaqtida tekshiriladi — xato qilish mumkin emas. Izolyatsiya xatolari ish vaqtida emas, balki kompilyatsiya vaqtida paydo bo'ladi.
Property Wrapper bu xususiyat deklaratsiyasini o'zgartirmasdan unga xatti-harakat qo'shadigan annotatsiyadir. SwiftUI va Combine ko'rinish holatini boshqarish uchun o'rnatilgan o'ramlarni taqdim etadi. Kompilyator xususiyatga kirishni o'rab, kuzatish, sinxronizatsiya yoki transformatsiya mantiqini qo'shadigan kod yaratadi.
@Published ObservableObject ga mos keladigan sinflarda o'zgarishlarni avtomatik nashr qilish uchun ishlatiladi. Combine obunachilari har bir yangilanishda bildirishnoma oladi. @State SwiftUI ko'rinishining mahalliy holatidir. @State o'zgarganda SwiftUI avtomatik ravishda ko'rinishni qayta chizadi. @Binding ma'lumotlarga egalik qilmasdan ota va bola ko'rinish o'rtasida ikki tomonlama aloqa yaratadi.
import SwiftUI
import Combine
@main
struct CounterApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class CounterViewModel: ObservableObject {
@Published var count: Int = 0
func increment() {
count += 1
}
}
struct ContentView: View {
@State private var greeting: String = "Salom"
@StateObject private var viewModel = CounterViewModel()
var body: some View {
VStack {
CounterDisplay(count: $viewModel.count)
Text(greeting)
Button("Oshirish", action: viewModel.increment)
}
}
}
struct CounterDisplay: View {
@Binding var count: Int
var body: some View {
Text("Sanoq: \(count)")
}
}
Maxsus Property Wrappers @propertyWrapper va wrappedValue maydoniga ega tuzilma orqali yaratiladi. Bu mantiqni qayta ishlatishga imkon beradi: tekshirish, normalizatsiya, UserDefaults saqlash. Property Wrappers shablon kodni sezilarli darajada kamaytiradi va annotatsiya orqali dasturchining niyatini aniq qiladi.
@propertyWrapper
struct Clamped<T: Comparable> {
private var value: T
let range: ClosedRange<T>
init(wrappedValue: T, range: ClosedRange<T>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
var wrappedValue: T {
get { value }
set { value = min(max(newValue, range.lowerBound), range.upperBound) }
}
}
struct Settings {
@Clamped(range: 0...100) var volume: Int = 50
}
var s = Settings()
s.volume = 150
// s.volume === 100 — qiymat avtomatik cheklangan
Generics tur xavfsizligini yo'qotmasdan moslashuvchan kod yozish uchun Swift-ning kuchli mexanizmidir. Umumiy funksiyalar va turlar cheklovlarni qondiradigan har qanday tur bilan ishlaydi. Protokolga Yo'naltirilgan Dasturlash (POP) bu protocol + extension klassik sinf meros olish o'rnini bosadigan, xatti-harakat kompozitsiyasini ta'minlaydigan Swift paradigmasi.
Swift protokollar (where bandlari) bilan umumiy parametrlarni cheklashga imkon beradi. Bog'langan turga ega protokol protokollar uchun umumiy ekvivalentdir: aniq tur moslashish vaqtida aniqlanadi. Bu tur xavfsiz to'plamlar va algoritmlar uchun asosdir. Swift standart kutubxonasi Generics-dan faol foydalanadi: Array, Dictionary, Optional — hammasi umumiy turlardir.
protocol Cacheable {
associatedtype Key: Hashable
associatedtype Value
func get(_ key: Key) -> Value?
mutating func set(_ value: Value, for key: Key)
}
struct MemoryCache<K: Hashable, V>: Cacheable {
private var storage: [K: V] = [:]
typealias Key = K
typealias Value = V
func get(_ key: K) -> V? {
return storage[key]
}
mutating func set(_ value: V, for key: K) {
storage[key] = value
}
}
func firstMatch<T: Equatable>(in array: [T], target: T) -> Int? {
for (index, item) in array.enumerated() {
if item == target {
return index
}
}
return nil
}
let numbers = [10, 20, 30, 40]
let index = firstMatch(in: numbers, target: 30)
// index === 2 — barcha Equatable turlari uchun bitta umumiy metod
Protokol extension POP ning asosiy mexanizmidir. Extension-da protokol metodlarining standart implementatsiyasi taqdim etilishi mumkin. Protokolga mos keladigan turlar bu implementatsiyani bepul oladi va kerak bo'lganda uni override qilishi mumkin. Bu sinf meros olmasdan xatti-harakat ierarxiyasini qurishga imkon beradi — Swift-da mavjud bo'lmagan ko'p meros olishga alternativa.
protocol Drivable {
var speed: Double { get set }
func drive()
}
extension Drivable {
func drive() {
if speed > 0 {
print("\(speed) km/soat tezlikda haydash")
}
}
}
struct Bicycle: Drivable {
var speed: Double = 15
}
struct Plane: Drivable {
var speed: Double = 900
func drive() {
print("\(speed) km/soat tezlikda uchish")
}
}
let bike = Bicycle()
bike.drive() // "15.0 km/soat tezlikda haydash" — standart
let plane = Plane()
plane.drive() // "900.0 km/soat tezlikda uchish" — override
Extension bilan POP bir nechta protokollar orqali kompozitsiya beradi — bir tur bir nechta protokolga mos kelishi va ularning implementatsiyalarini olishi mumkin. Bu butun ierarxiya qat'iy bo'lgan yagona sinf meros olishdan ko'ra moslashuvchanroq. Swift standart kutubxonasi POP asosida qurilgan: CustomStringConvertible, Equatable, Hashable, Codable — hammasi extension ga ega protokollar.
Enum Swift-da boshqa tillarga nisbatan ancha kuchli konstruksiyadir. Har bir hol bog'langan qiymatlarga ega bo'lishi mumkin — har qanday turdagi ixtiyoriy ma'lumotlar to'plami. Extension va pattern matching bilan birgalikda enum holatlar, operatsiya natijalari va chekli holat mashinalarini modellashtirish uchun asos bo'ladi.
Bog'langan qiymatlar har bir holga noyob ma'lumotlarni saqlashga imkon beradi. Masalan, loading holati ma'lumotlarni o'z ichiga olmaydi, success natijani o'z ichiga oladi, failure xatoni o'z ichiga oladi. Switch orqali pattern matching bog'langan qiymatlarni chiqaradi va har bir holni qayta ishlaydi. Kompilyator to'liqlikni tekshiradi (exhaustive switch) — bu unutilgan holatlarni yo'q qiladi.
enum NetworkResult<T> {
case loading
case success(T)
case failure(Error)
}
enum MediaFile {
case image(url: URL, width: Int, height: Int)
case video(url: URL, duration: Double)
case audio(url: URL, bitrate: Int)
}
func handle(_ result: NetworkResult<String>) {
switch result {
case .loading:
print("Yuklanmoqda...")
case .success(let data):
print("Qabul qilindi: \(data)")
case .failure(let error):
print("Xato: \(error.localizedDescription)")
}
}
let file = MediaFile.video(url: URL(string: "https://example.com/video.mp4")!, duration: 120)
if case .video(let url, let duration) = file {
print("Video \(url) davomiylik \(duration)s")
}
Swift enum uchun extension orqali metodlar, hisoblangan xususiyatlar va protokolga moslik qo'shishga imkon beradi. Bu asl deklaratsiyani o'zgartirishni talab qilmaydi — kod toza va modulli qoladi. Extension-dagi metodlar bog'langan qiymatlar bilan ishlashi, hosila ma'lumotlarni hisoblashi va biznes mantiqini amalga oshirishi mumkin.
extension MediaFile {
var fileName: String {
switch self {
case .image(let url, _, _),
.video(let url, _),
.audio(let url, _):
return url.lastPathComponent
}
}
var description: String {
switch self {
case .image(_, let w, let h):
return "Rasm \(w)x\(h)"
case .video(_, let d):
return "Video \(d)s"
case .audio(_, let b):
return "Audio \(b) kbps"
}
}
}
extension MediaFile: Equatable {
static func == (lhs: MediaFile, rhs: MediaFile) -> Bool {
return lhs.fileName == rhs.fileName
}
}
let files: [MediaFile] = [file]
files.forEach { print($0.description) }
// "Video 120.0s"
Bog'langan qiymatlar + Extension bilan Enum Kotlin-dagi muhrlangan sinflar yoki boshqa tillardagi diskriminatsiyalangan birlashmalarning o'rnini bosadi. Swift bu kombinatsiyani Result (standart kutubxonadagi standart tur), Optional (Optional .none va .some bilan enum) va SwiftUI-da holatni boshqarish uchun ishlatadi. Pattern matching barcha holatlarning qayta ishlanishini kafolatlaydi — ish vaqti xatolari mumkin emas.
Tez-tez beriladigan savollar
Struct — qiymat turi, tayinlashda nusxalanadi, meros olishni qo'llab-quvvatlamaydi. Class — mos yozuv turi, mos yozuv orqali uzatiladi, meros olish, deinit va identifikatsiya tekshirishni (===) qo'llab-quvvatlaydi. Apple struct bilan boshlashni va faqat mos yozuv semantikasi kerak bo'lganda class ga o'tishni tavsiya qiladi.
Actor — thread xavfsiz mos yozuv turi. Kompilyator turli kontekstlardan o'zgaruvchan holatga bir vaqtda kirishni taqiqlaydi. Bir nechta vazifalar tomonidan kiriladigan holat menejerlari, keshlar va xizmatlar uchun Actor dan foydalaning. Actor metodlarini chaqirish await talab qiladi.
Asosiylari: @State — mahalliy ko'rinish holati; @Binding — egaliksiz ma'lumot ulanishi; @Published — ObservableObject-da o'zgarishlarni nashr qilish; @StateObject — ObservableObject egaligi; @EnvironmentObject — muhitga bog'liqlik. Maxsus o'ramlar @propertyWrapper orqali yaratiladi.
POP — sinf meros olish o'rniga protocol + extension xatti-harakatni belgilaydigan paradigmadir. Bir tur bir nechta protokolga mos keladi va ularning implementatsiyalarini bepul oladi. Bu meros olish o'rniga kompozitsiya — moslashuvchanroq va xavfsizroq. Swift standart kutubxonasi (Equatable, Codable) POP asosida qurilgan.
Swift-da enum bog'langan qiymatlarni qo'llab-quvvatlaydi — har bir hol turli xil turlardagi ixtiyoriy ma'lumotlarni saqlashi mumkin. Pattern matching (switch) bilan birgalikda bu holatlar, xatolar va Domain-Driven Design uchun kuchli modelni ta'minlaydi. Optional va Result bog'langan qiymatlarga ega standart Swift enum laridir.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.