Swift Apple-ın proqramlaşdırma dilidir, Objective-C-nin gücünü müasir dillərin təhlükəsizliyi ilə birləşdirir. Bir çox digər dillərdən fərqli olaraq, Swift unikal konstruksiyalar təklif edir: avtomatik surətlə dəyər tipləri, kompilyator səviyyəsində izolyasiya ilə Actors, xassə məntiqini təkrar istifadə üçün Property Wrappers və klassik miras alma yerinə Protokol Yönümlü Proqramlaşdırma.Apple Swift Sənədləri'nə görə, bu xüsusiyyətlər kodu daha təhlükəsiz və səmərəli edir.
Əsas Məqamlar
Swift-də struct dəyər tipidir, class isə istinad tipidir. Bu əsas fərq təyin etmə, funksiyalara ötürmə və yaddaş idarəetməsi zamanı davranışı müəyyən edir. Struct hər təyinatda tamamilə surəti çıxarılır, class istinadla ötürülür — yalnız heap-dəki obyektə göstərici surəti çıxarılır.
Struct avtomatik olaraq dəyər semantikasını tətbiq edir — hər bir nüsxə müstəqildir. Struct xassəsinin dəyişdirilməsi yalnız var vasitəsilə mümkündür və xassələri dəyişdirən metodlar mutating olaraq qeyd edilməlidir. Struct miras almanı dəstəkləmir, lakin protokollara uyğunlaşa bilər. Swift-in standart kitabxanası String, Array, Dictionary, Int, Bool üçün struct istifadə edir — bütün əsas tiplər dəyər tipləridir.
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"
// Tam surət — müstəqil nüsxələr
Class heap-də saxlanılır və istinad bərabərliyini dəstəkləyir. Bir neçə dəyişən eyni obyektə istinad edə bilər, bir istinad vasitəsilə dəyişikliklər bütün digərlərində görünür. Class miras almanı dəstəkləyir, metodları override etməyə imkan verir, resurs təmizləməsi üçün deinit-ə malikdir. Swift-də class struct-dan daha az istifadə olunur — Apple struct ilə başlamağı və yalnız miras alma və ya istinad semantikası lazım olduqda class-a keçməyi tövsiyə edir.
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
// Eyni istinad — dəyişikliklər hər yerdə görünür
struct və class arasında seçim məlumat semantikasından asılıdır. Konfiqurasiyalar, məlumat modelləri və vəziyyətlər üçün struct istifadə edin — surəti çıxarmaq daha təhlükəsiz və proqnozlaşdırıla biləndir. Kimliyi olan obyektlər (istifadəçi sessiyası, verilənlər bazası əlaqəsi) və miras alma lazım olduqda class istifadə edin.
Actor dəyişkən vəziyyətini eyni vaxtda girişdən qoruyan istinad tipidir. Swift kompilyatoru actor dəyişənlərinə yalnız eyni actor kontekstindən daxil oluna biləcəyini təmin edir — hər hansı xarici giriş kompilyasiya xətasına səbəb olur. Bu, əl ilə kilidləmələr olmadan dil səviyyəsində məlumat yarışlarının qarşısını alır.
Bütün actor xassələri və metodları defolt olaraq izolyasiya olunur. Xaricdən actor metodunu çağırmaq await tələb edir — Swift icranı actor-a keçir və geri qaytarır. Actor girişi ardıcıl olaraq sinxronlaşdırır: müxtəlif tapşırıqlardan sorğular növbəyə düzülür. Bu, actor daxilində ardıcıl vəziyyəti təmin edir. Qeyri-izolyasiya olunmuş metodlar (nonisolated) await olmadan çağrıla bilər, lakin dəyişkən xassələrə daxil ola bilməz.
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 Hesabı"
}
}
let account = BankAccount(initialBalance: 1000)
await account.deposit(amount: 500)
// balance = 1500 — atomik, yarış vəziyyəti yoxdur
Actor vəziyyət menecerləri, keşlər və şəbəkə xidmətləri üçün faydalıdır, burada bir neçə tapşırıq eyni vaxtda məlumatları oxuyur və yazır. NSLock və ya DispatchQueue ilə əl ilə sinxronizasiyadan fərqli olaraq, actor kompilyasiya vaxtı yoxlanılır — səhv etmək mümkün deyil. İzolyasiya səhvləri iş vaxtında deyil, kompilyasiya vaxtında görünür.
Property Wrapper bəyannaməsini dəyişmədən xassəyə davranış əlavə edən annotasiyadır. SwiftUI və Combine görünüş vəziyyətini idarə etmək üçün daxili sarıcılar təqdim edir. Kompilyator xassə girişini sarıyan, müşahidə, sinxronizasiya və ya transformasiya məntiqi əlavə edən kod yaradır.
@Published ObservableObject-ə uyğunlaşan siniflərdə dəyişiklikləri avtomatik yayımlamaq üçün istifadə olunur. Combine abunəçiləri hər yeniləmədə bildiriş alır. @State SwiftUI görünüşünün yerli vəziyyətidir. @State dəyişdikdə SwiftUI avtomatik olaraq görünüşü yenidən çəkir. @Binding məlumatlara sahib olmadan valideyn və uşaq görünüşü arasında ikitərəfli əlaqə yaradır.
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 = "Salam"
@StateObject private var viewModel = CounterViewModel()
var body: some View {
VStack {
CounterDisplay(count: $viewModel.count)
Text(greeting)
Button("Artır", action: viewModel.increment)
}
}
}
struct CounterDisplay: View {
@Binding var count: Int
var body: some View {
Text("Say: \(count)")
}
}
Xüsusi Property Wrappers @propertyWrapper və wrappedValue sahəsi olan struktur vasitəsilə yaradılır. Bu, məntiqin təkrar istifadəsinə imkan verir: doğrulama, normallaşdırma, UserDefaults saxlama. Property Wrappers şablon kodu əhəmiyyətli dərəcədə azaldır və annotasiya vasitəsilə tərtibatçının niyyətini aydın edir.
@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 — dəyər avtomatik məhdudlaşdırıldı
Generics tip təhlükəsizliyini itirmədən çevik kod yazmaq üçün Swift-in güclü mexanizmidir. Ümumi funksiyalar və tiplər məhdudiyyətləri ödəyən istənilən tiplə işləyir. Protokol Yönümlü Proqramlaşdırma (POP) klassik sinif miras almasını əvəz edən, davranış kompozisiyasını təmin edən Swift paradiqmasıdır.
Swift protokollarla (where bəndləri) ümumi parametrləri məhdudlaşdırmağa imkan verir. Əlaqəli tipə malik protokol protokollar üçün ümumi ekvivalentdir: konkret tip uyğunlaşma anında müəyyən edilir. Bu, tip təhlükəsiz kolleksiyalar və alqoritmlər üçün əsasdır. Swift-in standart kitabxanası Generics-dən fəal istifadə edir: Array, Dictionary, Optional — hamısı ümumi tiplərdir.
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 — bütün Equatable tipləri üçün bir ümumi metod
Protokol extension POP-un əsas mexanizmidir. Extension-da protokol metodlarının defolt tətbiqi təmin edilə bilər. Protokola uyğunlaşan tiplər bu tətbiqi pulsuz alır və lazım olduqda onu override edə bilər. Bu, sinif miras alması olmadan davranış iyerarxiyası qurmağa imkan verir — Swift-də mövcud olmayan çoxlu miras almaya alternativdir.
protocol Drivable {
var speed: Double { get set }
func drive()
}
extension Drivable {
func drive() {
if speed > 0 {
print("\(speed) km/saat sürətlə sürmə")
}
}
}
struct Bicycle: Drivable {
var speed: Double = 15
}
struct Plane: Drivable {
var speed: Double = 900
func drive() {
print("\(speed) km/saat sürətlə uçuş")
}
}
let bike = Bicycle()
bike.drive() // "15.0 km/saat sürətlə sürmə" — defolt
let plane = Plane()
plane.drive() // "900.0 km/saat sürətlə uçuş" — override
Extension ilə POP çoxsaylı protokollar vasitəsilə kompozisiya təmin edir — bir tip bir neçə protokola uyğunlaşa və onların tətbiqlərini əldə edə bilər. Bu, bütün iyerarxiyanın sabit olduğu tək sinif miras almasından daha çevikdir. Swift-in standart kitabxanası POP üzərində qurulub: CustomStringConvertible, Equatable, Hashable, Codable — hamısı extension-a malik protokollardır.
Enum Swift-də digər dillərə nisbətən əhəmiyyətli dərəcədə daha güclü konstruksiyadır. Hər bir hal əlaqəli dəyərlərə malik ola bilər — istənilən tipdən ixtiyari məlumat dəsti. Extension və pattern matching ilə birlikdə enum vəziyyətlərin, əməliyyat nəticələrinin və sonlu vəziyyət maşınlarının modelləşdirilməsi üçün əsas olur.
Əlaqəli dəyərlər hər bir halın unikal məlumat saxlamasına imkan verir. Məsələn, loading halında məlumat yoxdur, success nəticəni ehtiva edir, failure xətanı ehtiva edir. Switch vasitəsilə pattern matching əlaqəli dəyərləri çıxarır və hər bir halı emal edir. Kompilyator tamlığı yoxlayır (exhaustive switch) — bu, unudulmuş vəziyyətləri aradan qaldırır.
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("Yüklənir...")
case .success(let data):
print("Alındı: \(data)")
case .failure(let error):
print("Xəta: \(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) müddət \(duration)s")
}
Swift enum üçün extension vasitəsilə metodlar, hesablanmış xassələr və protokol uyğunluğu əlavə etməyə imkan verir. Bu, orijinal bəyannaməni dəyişdirməyi tələb etmir — kod təmiz və modulyar qalır. Extension-dakı metodlar əlaqəli dəyərlərlə işləyə, törəmə məlumatları hesablaya və biznes məntiqini tətbiq edə bilər.
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 "Şəkil \(w)x\(h)"
case .video(_, let d):
return "Video \(d)s"
case .audio(_, let b):
return "Səs \(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"
Əlaqəli dəyərlər + Extension ilə Enum Kotlin-dəki möhürlənmiş siniflərin və ya digər dillərdəki ayrı-seçki birləşmələrinin əvəzidir. Swift bu kombinasiyanı Result (standart kitabxanada standart tip), Optional (Optional .none və .some ilə enum-dur) və SwiftUI-də vəziyyətin idarə edilməsi üçün istifadə edir. Pattern matching bütün vəziyyətlərin işləndiyini təmin edir — iş vaxtı səhvləri mümkün deyil.
Tez-tez verilən suallar
Struct — dəyər tipi, təyin edildikdə surəti çıxarılır, miras almanı dəstəkləmir. Class — istinad tipi, istinadla ötürülür, miras alma, deinit və kimlik yoxlamasını (===) dəstəkləyir. Apple struct ilə başlamağı və yalnız istinad semantikası lazım olduqda class-a keçməyi tövsiyə edir.
Actor — thread təhlükəsiz istinad tipi. Kompilyator müxtəlif kontekstlərdən dəyişkən vəziyyətə eyni vaxtda girişi qadağan edir. Bir neçə tapşırıq tərəfindən girişilən vəziyyət menecerləri, keşlər və xidmətlər üçün Actor istifadə edin. Actor metodlarını çağırmaq await tələb edir.
Əsas: @State — yerli görünüş vəziyyəti; @Binding — sahiblik olmadan məlumat əlaqəsi; @Published — ObservableObject-də dəyişikliklərin yayımı; @StateObject — ObservableObject sahibliyi; @EnvironmentObject — mühitdən asılılıq. Xüsusi sarıcılar @propertyWrapper vasitəsilə yaradılır.
POP — sinif miras alması əvəzinə protocol + extension-un davranışı təyin etdiyi paradiqmadır. Bir tip bir neçə protokola uyğunlaşır və onların tətbiqlərini pulsuz alır. Bu, miras alma əvəzinə kompozisiyadır — daha çevik və təhlükəsizdir. Swift-in standart kitabxanası (Equatable, Codable) POP üzərində qurulub.
Swift-də enum əlaqəli dəyərləri dəstəkləyir — hər bir hal müxtəlif tipli ixtiyari məlumat saxlaya bilər. Pattern matching (switch) ilə birlikdə bu, vəziyyətlər, xətalar və Domain-Driven Design üçün güclü model təmin edir. Optional və Result əlaqəli dəyərlərə malik standart Swift enum-larıdır.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.