Class — Swift dilində referans tipidir (reference type), onun nümunələri təyinat zamanı kopyalanmayıb referans vasitəsilə ötürülür. Strukturlardan fərqli olaraq, siniflər miras, deinitsializasiya və yaddaşı idarə etmək üçün avtomatik referans sayma ARC-ni dəstəkləyir. Swift Programming Language Guide, 2026-ya görə, class Apple-ın UI freymvorkları (UIKit, AppKit) ilə işləmək və obyektin ümumi eyniliyini tələb edən nümunələri həyata keçirmək üçün lazımdır. Class və struct arasında seçim Swift-də əsas memarlıq qərarlarından biridir.
Əsas məqamlar
Class (sinif) — Swift-də xassə və metodları miras və dinamik göndərmə dəstəyi ilə vahid bir qurumda qruplaşdıran mürəkkəb referans tipidir. Struct-dan fərqli olaraq, sinif nümunəsi yığında (heap) yaradılır və dəyişən bu nümunəyə referans saxlayır, öz məlumatları yox.
Sinif dəyişənini başqa dəyişənə təyin etdikdə, hər ikisi yaddaşda eyni obyektə istinad edir. Bir referans vasitəsilə edilən dəyişikliklər digərindən görünür — bu, delegasiya, müşahidə və birgə vəziyyət nümunələrində istifadə olunan reference types-ın əsas xüsusiyyətidir.
Apple Swift Documentation-ya görə, siniflər UIKit və AppKit ilə işləməyin yeganə yoludur, burada bütün UI komponentləri UIView və UIViewController-dən miras alır. Bundan əlavə, siniflər obyekt eyniliyi (bir obyektə iki referans) və idarə olunan həyat müddəti tələb edən nümunələrin həyata keçirilməsi üçün zəruridir.
Reference type semantikası — siniflərin əsas xüsusiyyətidir. Sinif yeni dəyişənə təyin edilərkən Swift referansı kopyalayır, məlumatları yox. Bir nümunəyə istinad edən bütün dəyişənlər onun cari vəziyyətini görür və dəyişə bilər. Bu davranış hər dəyişənin müstəqil kopya aldığı value types-dan prinsipial olaraq fərqlənir.
// Reference type semantikası nümunəsi
class User {
var name: String
init(name: String) { self.name = name }
}
let user1 = User(name: "Alice")
let user2 = user1 // user2 — eyni referans
user2.name = "Bob"
print(user1.name) // "Bob" — user2 vasitəsilə dəyişdirildi!
// === operatoru ilə eynilik yoxlanışı
print(user1 === user2) // true — eyni obyekt
=== (eynilik) və !== operatorları iki dəyişənin eyni sinif nümunəsinə istinad edib-etmədiyini yoxlayır. Bu, xassələrin dəyərlərini müqayisə edən == (bərabərlik) ilə fərqlənir. Struct üçün === operatoru mövcud deyil — value types-ın eyniliyi yoxdur.
Miras — sinfin valideyn sinfinin xassə və metodlarını mənimsəyə biləcəyi mexanizmdir. Swift-də sinif yalnız bir valideyndən miras ala bilər (single inheritance), lakin bir çox protokolu tətbiq edə bilər. override açar sözü miras alınan metodu və ya xassəni yenidən təyin etməyə imkan verir.
Başqa sinifdən miras almayan hər bir sinif avtomatik olaraq baza sinfi olur (NSObject ilə qarışdırmayın). Alt sinif adından sonra iki nöqtə ilə valideyni göstərir. Alt sinif valideynin metodunu yenidən təyin edərsə, valideyn davranışını qorumaq üçün super.metodunu() çağırmalıdır — bu kompilyator tələbidir.
final açar sözü class-dan əvvəl miras almanı qadağan edir. Kompilyator final sinif metodlarının çağırışlarını static dispatch vasitəsilə optimallaşdıra bilər, bu da performansı artırır. Genişləndirilməsi nəzərdə tutulmayan siniflər üçün final istifadə edin — bu niyyətinizi sənədləşdirir və kodu sürətləndirir.
// Swift-də sinif mirası nümunəsi
class Vehicle {
var speed: Double = 0
func description() -> String {
"Speed: \(speed) km/h"
}
}
// Car Vehicle-dən miras alır
class Car: Vehicle {
var brand: String = "Unknown"
override func description() -> String {
"\(brand) - \(speed) km/h"
}
}
// Final class — mirası qadağan edir
final class ElectricCar: Car {
var batteryLevel: Double = 100
}
let tesla = ElectricCar()
tesla.brand = "Tesla"
tesla.speed = 120
print(tesla.description()) // "Tesla - 120.0 km/s"
Sinif mirası güclü, lakin məsuliyyətli mexanizmdir. Dərin iyerarxiya (5+ səviyyə) kodu dəstəkləməyi və test etməyi çətinləşdirir. Mirassız funksionallığın təkrar istifadəsi üçün protokollardan extension və protokol yönümlü proqramlaşdırma ilə istifadə edin — Apple bu yanaşmanı dərin sinif iyerarxiyalarına alternativ olaraq təşviq edir.
Swift siniflərin yaddaşını idarə etmək üçün ARC (Automatic Reference Counting) istifadə edir. Hər bir sinif nümunəsinin güclü referans sayğacı var. Yeni güclü referans yaradıldıqda sayğac artır; məhv edildikdə azalır. Sayğac sıfıra çatdıqda yaddaş azad edilir.
Deinit — sinif nümunəsi azad edilməzdən əvvəl avtomatik çağırılan metoddur. Burada resurslar azad edilir: fayllar bağlanır, bildirişlərdən çıxılır, taymerlər dayandırılır. Deinit yalnız siniflərdə var — strukturlar və sadalamalar onu yoxdur.
Güclü referans dövrlərinin (retain cycles) qarşısını almaq üçün Swift weak və unowned referansları təqdim edir. Weak — obyekt azad edildikdə avtomatik nil olan opsional referansdır. Unowned — qeyri-opsional, lakin cari kontekstdən daha uzun yaşayacağı zəmanət verilən obyektə istinad edir. Tipik retain cycle parent-child əlaqəsində yaranır: child valideynə güclü referans saxlayır.
// ARC və zəif referans nümunəsi
class Parent {
var name: String
var child: Child?
init(name: String) { self.name = name }
deinit { print("\(name) dealokasiya edildi") }
}
class Child {
var name: String
weak var parent: Parent? // weak retain cycle-ın qarşısını alır
init(name: String) { self.name = name }
deinit { print("\(name) dealokasiya edildi") }
}
var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent
parent = nil // Hər iki obyekt dealokasiya edildi!
// Weak olmadan retain cycle yaranardı
Uşaq obyektdən valideynə olan referanslar və bağlanmalardakı capture siyahıları üçün həmişə weak istifadə edin. Unowned yalnız obyektin cari kontekstdən daha uzun yaşayacağına əmin olduqda istifadə edin — unowned-ın səhv istifadəsi azad edilmiş yaddaşa müraciət zamanı crash-a səbəb ola bilər.
Class və struct arasında seçim performansa, thread təhlükəsizliyinə və API dizaynına təsir edən memarlıq qərarıdır. Hər bir konkret halda düzgün qərar verməyə kömək edəcək əsas fərqlər cədvəlinə baxaq.
| Xüsusiyyət | class | struct |
|---|---|---|
| Tip | Reference type (referans) | Value type (kopya) |
| Yaddaş | Yığın (heap) + ARC | Stack / inline |
| Miras | Dəstəkləyir (bir valideyn) | Dəstəkləmir |
| Deinit | Var | Yox |
| Eynilik (===) | Dəstəkləyir | Dəstəkləmir |
| Mutating | Tələb olunmur (həmişə mutating) | Yalnız mutating ilə |
| Memberwise init | Generasiya olunmur | Avtomatik generasiya olunur |
| Thread təhlükəsizliyi | Zəmanət verilmir (paylaşılan vəziyyət) | Zəmanət verilir (kopyalama) |
Sinifləri ümumi eynilik (kodun bir neçə hissəsi bir obyektlə işləyir), miras və ya Objective-C runtime ilə qarşılıqlı əlaqə lazım olduqda istifadə edin. Qalan hər şey üçün strukturlar üstünlük təşkil edir — onlar daha sürətli, çoxiplikli kodda daha təhlükəsizdir və yaddaş idarəsi tələb etmir.
Apple-ın default olaraq struct istifadə etmə tövsiyəsinə baxmayaraq, bir neçə konkret ssenaridə siniflər zəruridir. Hər birini praktiki nümunələrlə nəzərdən keçirək.
iOS və macOS-da bütün UI komponentləri UIView (iOS) və ya NSView (macOS) siniflərindən miras alan siniflərdir. UIViewController-i struct ilə əvəz edə bilməzsiniz — o, miras və resursları azad etmək üçün deinit tələb edir. UIKit ilə işləyərkən kontrollerlər, view-lər və onların delegate-ləri üçün siniflərdən istifadə edin.
Singleton nümunəsi (bütün tətbiq üçün bir sinif nümunəsi) referans semantikası tələb edir. Menecerlər: NetworkManager, SettingsManager, AnalyticsService — adətən shared static property ilə siniflər kimi tətbiq edilir. Strukturlar uyğun deyil, çünki hər kopya müstəqil nümunə olacaqdır.
Obyekt tək həqiqət mənbəyi (single source of truth) olduqda və modullar arasında referans vasitəsilə ötürüldükdə class istifadə edin. Bu, obyektin bir yerdə dəyişdirilməsinin bütün asılı komponentlərdə görünməli olduğu vəziyyət idarəçiliyinə aiddir. SwiftUI-də ObservableObject üçün siniflər məcburidir.
// ObservableObject — SwiftUI üçün class tələb olunur
import SwiftUI
class AppViewModel: ObservableObject {
@Published var isLoggedIn: Bool = false
@Published var username: String = ""
func login(user: String) {
isLoggedIn = true
username = user
}
}
// SwiftUI View-də istifadə
struct ContentView: View {
@StateObject var viewModel = AppViewModel()
var body: some View {
Text(viewModel.isLoggedIn ? "Xoş gəldiniz" : "Daxil ol")
}
}
Qayda: əgər obyektin eynilik (iki referans -> bir obyekt) olmalıdırsa, tək nümunə olmalıdırsa və ya UIKit/Objective-C ilə işləməlidirsə — class seçin. Əgər obyekt sadəcə məlumat saxlayırsa — struct seçin.
Tez-tez verilən suallar
Class — Swift-də miras, deinitsializasiya və yaddaşın idarə edilməsi üçün ARC-ni dəstəkləyən referans tipidir (reference type). Sinif nümunələri yığında saxlanılır, dəyişənlər isə obyektə referans ehtiva edir, onun surətini yox.
Class — reference type (referansla ötürülür), miras və deinit-i dəstəkləyir. Struct — value type (kopyalanır), mirası dəstəkləmir, lakin protokolları tətbiq edir və memberwise init-i avtomatik alır. Swift default tip olaraq struct-ı tövsiyə edir.
ARC (Automatic Reference Counting) — Swift sinifləri üçün yaddaşın idarə edilməsi mexanizmidir. Hər nümunənin güclü referans sayğacı var. Sayğac sıfırlandıqda yaddaş azad edilir. Weak və unowned referanslar obyektlər arasında güclü referans dövrlərinin qarşısını alır.
Deinit — yaddaşı azad edilməzdən əvvəl avtomatik çağırılan sinif metodudur. Faylları bağlamaq, bildirişlərdən çıxmaq və digər yekun əməliyyatlar üçün istifadə olunur. Deinit yalnız siniflərdə mövcuddur — strukturlarda yoxdur.
Class UIKit/AppKit UI komponentləri, singleton, SwiftUI-də ObservableObject, ümumi eyniliyi olan obyektlər (delegate, observer) və Objective-C runtime ilə iş üçün istifadə edin. Məlumat modelləri, DTO və konfiqurasiyalar üçün struct üstünlük təşkil edir.
Nəticə
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.
Həm də oxuyun