class — چیست، مفاهیم کلیدی و اصل کار در Swift

نویسنده: IT Sectr منتشر شده: 2026-06-17 زمان مطالعه: 8 دقیقه

Class — یک نوع مرجع (reference type) در زبان Swift است که نمونه‌های آن با ارجاع منتقل می‌شوند، نه با کپی کردن در هنگام تخصیص. برخلاف ساختارها، کلاس‌ها از وراثت، مقدارزدایی و شمارش خودکار مراجع ARC برای مدیریت حافظه پشتیبانی می‌کنند. به گفته Swift Programming Language Guide, 2026، class برای کار با چارچوب‌های UI اپل (UIKit, AppKit) و پیاده‌سازی الگوهایی که نیاز به هویت مشترک شیء دارند ضروری است. انتخاب بین class و struct یکی از تصمیم‌های کلیدی معماری در Swift است.

نکات اصلی

  • Class — reference type در Swift، جایی که متغیر یک ارجاع به شیء در heap را ذخیره می‌کند، نه خود مقدار.
  • وراثت — کلاس‌ها می‌توانند ویژگی‌ها و متدهای کلاس والد را به ارث ببرند و آنها را با override بازنویسی کنند.
  • ARC — شمارش خودکار مراجع، حافظه را زمانی آزاد می‌کند که هیچ ارجاع قوی به شیء باقی نماند.
  • Deinit — متد ویژه‌ای که قبل از آزادسازی شیء برای پاکسازی منابع فراخوانی می‌شود.
  • هویت — عملگرهای === و !== بررسی می‌کنند که آیا دو متغیر به یک نمونه از کلاس ارجاع می‌دهند.

class در Swift چیست؟

Class (کلاس) — یک نوع مرجع ترکیبی در Swift است که ویژگی‌ها و متدها را در یک موجودیت واحد با پشتیبانی از وراثت و ارسال پویا گروه‌بندی می‌کند. برخلاف struct، نمونه کلاس در heap ایجاد می‌شود و متغیر یک ارجاع به این نمونه را ذخیره می‌کند، نه خود داده‌ها.

وقتی یک متغیر کلاس را به متغیر دیگری تخصیص می‌دهید، هر دو به یک شیء در حافظه ارجاع می‌دهند. تغییرات از طریق یک ارجاع از طریق دیگری قابل مشاهده است — این ویژگی بنیادی reference types است که در الگوهای تفویض اختیار، مشاهده و حالت اشتراکی استفاده می‌شود.

به گفته Apple Swift Documentation، کلاس‌ها تنها راه کار با UIKit و AppKit هستند، جایی که همه کامپوننت‌های UI از UIView و UIViewController ارث می‌برند. علاوه بر این، کلاس‌ها برای پیاده‌سازی الگوهایی که نیاز به هویت شیء (دو ارجاع به یک شیء) و طول عمر کنترل‌شده دارند ضروری هستند.

Class به عنوان reference type

معناشناسی reference type — ویژگی کلیدی کلاس‌هاست. هنگام تخصیص کلاس به یک متغیر جدید، Swift ارجاع را کپی می‌کند، نه داده‌ها را. همه متغیرهایی که به یک نمونه ارجاع می‌دهند وضعیت فعلی آن را می‌بینند و می‌توانند آن را تغییر دهند. این رفتار اساساً با value types متفاوت است، جایی که هر متغیر یک کپی مستقل دریافت می‌کند.

swift
// مثال معناشناسی reference type
class User {
    var name: String
    init(name: String) { self.name = name }
}

let user1 = User(name: "Alice")
let user2 = user1           // user2 — ارجاع یکسان
user2.name = "Bob"

print(user1.name)               // "Bob" — از طریق user2 تغییر کرد!

// بررسی هویت با عملگر ===
print(user1 === user2)          // true — شیء یکسان

عملگرهای === (هویت) و !== بررسی می‌کنند که آیا دو متغیر به یک نمونه کلاس ارجاع می‌دهند. این تفاوت با == (برابری) است که مقادیر ویژگی‌ها را مقایسه می‌کند. برای struct عملگر === در دسترس نیست — value types هویت ندارند.

وراثت کلاس‌ها

وراثت — مکانیزمی که به یک کلاس امکان می‌دهد ویژگی‌ها و متدهای کلاس والد را به ارث ببرد. در Swift یک کلاس می‌تواند فقط از یک والد ارث ببرد (single inheritance)، اما می‌تواند چندین پروتکل را پیاده‌سازی کند. کلمه کلیدی override به شما امکان بازنویسی یک متد یا ویژگی به ارث برده را می‌دهد.

کلاس پایه و زیرکلاس

هر کلاسی که از کلاس دیگری ارث نمی‌برد به طور خودکار یک کلاس پایه می‌شود (با NSObject اشتباه نشود). زیرکلاس والد را با دو نقطه بعد از نام مشخص می‌کند. اگر زیرکلاس متد والد را بازنویسی کند، باید super.متد() را برای حفظ رفتار والد فراخوانی کند — این یک الزام کامپایلر است.

کلاس نهایی (Final class)

کلمه کلیدی final قبل از class وراثت را ممنوع می‌کند. کامپایلر می‌تواند فراخوانی‌های متدهای کلاس نهایی را از طریق static dispatch بهینه‌سازی کند که عملکرد را افزایش می‌دهد. از final برای کلاس‌هایی که برای گسترش در نظر گرفته نشده‌اند استفاده کنید — این قصد شما را مستند می‌کند و کد را سریع‌تر می‌کند.

swift
// مثال وراثت کلاس در Swift
class Vehicle {
    var speed: Double = 0

    func description() -> String {
        "Speed: \(speed) km/h"
    }
}

// Car از Vehicle ارث می‌برد
class Car: Vehicle {
    var brand: String = "Unknown"

    override func description() -> String {
        "\(brand) - \(speed) km/h"
    }
}

// Final class — از وراثت جلوگیری می‌کند
final class ElectricCar: Car {
    var batteryLevel: Double = 100
}

let tesla = ElectricCar()
tesla.brand = "Tesla"
tesla.speed = 120
print(tesla.description())  // "Tesla - 120.0 km/h"

وراثت کلاس‌ها مکانیزمی قدرتمند اما مسئولیت‌پذیر است. سلسله‌مراتب عمیق (5+ سطح) نگهداری و آزمایش را دشوار می‌کند. برای استفاده مجدد از قابلیت‌ها بدون وراثت از پروتکل‌ها با extension و برنامه‌نویسی پروتکل‌محور استفاده کنید — رویکردی که اپل به عنوان جایگزینی برای سلسله‌مراتب عمیق کلاس ترویج می‌کند.

مقدارزدایی و مدیریت حافظه

Swift از ARC (Automatic Reference Counting) برای مدیریت حافظه کلاس‌ها استفاده می‌کند. هر نمونه کلاس یک شمارنده ارجاع قوی دارد. هنگام ایجاد یک ارجاع قوی جدید شمارنده افزایش می‌یابد؛ هنگام نابودی کاهش می‌یابد. وقتی شمارنده به صفر می‌رسد، حافظه آزاد می‌شود.

Deinit

Deinit — متدی که به طور خودکار قبل از آزادسازی نمونه کلاس فراخوانی می‌شود. در آن منابع آزاد می‌شوند: فایل‌ها بسته می‌شوند، از اعلان‌ها لغو اشتراک می‌شود، تایمرها متوقف می‌شوند. Deinit فقط در کلاس‌ها وجود دارد — ساختارها و شمارش‌ها آن را ندارند.

ارجاعات ضعیف و بدون مالک

برای جلوگیری از چرخه‌های ارجاع قوی (retain cycles)، Swift ارجاعات weak و unowned را فراهم می‌کند. Weak — یک ارجاع اختیاری که با آزادسازی شیء به طور خودکار nil می‌شود. Unowned — غیراختیاری، اما به شیئی ارجاع می‌دهد که تضمین شده بیشتر از زمینه فعلی زنده می‌ماند. retain cycle معمولی در رابطه parent-child رخ می‌دهد: child یک ارجاع قوی به parent نگه می‌دارد.

swift
// مثال ARC و ارجاع ضعیف
class Parent {
    var name: String
    var child: Child?

    init(name: String) { self.name = name }
    deinit { print("\(name) آزاد شد") }
}

class Child {
    var name: String
    weak var parent: Parent?   // weak از retain cycle جلوگیری می‌کند

    init(name: String) { self.name = name }
    deinit { print("\(name) آزاد شد") }
}

var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent

parent = nil  // هر دو شیء آزاد شدند!
// بدون weak یک retain cycle ایجاد می‌شد

همیشه از weak برای ارجاعات از شیء فرزند به والد و برای لیست‌های capture در بسته‌ها استفاده کنید. Unowned را فقط زمانی استفاده کنید که مطمئن هستید شیء از زمینه فعلی بیشتر زنده می‌ماند — استفاده نادرست از unowned می‌تواند به crash هنگام دسترسی به حافظه آزادشده منجر شود.

Class vs Struct: تفاوت‌های کلیدی

انتخاب بین class و struct یک تصمیم معماری است که بر عملکرد، ایمنی نخ و طراحی API تأثیر می‌گذارد. جدول تفاوت‌های کلیدی را بررسی کنید که به اتخاذ تصمیم صحیح در هر مورد خاص کمک می‌کند.

ویژگیclassstruct
نوعReference type (ارجاع)Value type (کپی)
حافظهHeap + ARCStack / inline
وراثتپشتیبانی می‌کند (یک والد)پشتیبانی نمی‌کند
Deinitداردندارد
هویت (===)پشتیبانی می‌کندپشتیبانی نمی‌کند
Mutatingنیاز نیست (همیشه mutating)فقط با mutating
Memberwise initتولید نمی‌شودبه طور خودکار تولید می‌شود
ایمنی نختضمین نشده (حالت اشتراکی)تضمین شده (کپی‌برداری)

زمانی از کلاس‌ها استفاده کنید که به هویت مشترک (چند بخش کد با یک شیء کار می‌کنند)، وراثت یا تعامل با Objective-C runtime نیاز دارید. برای بقیه موارد ساختارها ترجیح داده می‌شوند — آنها سریع‌تر، در کد چندنخی ایمن‌تر هستند و نیاز به مدیریت حافظه ندارند.

چه زمانی از class در Swift استفاده کنیم

با وجود توصیه اپل به استفاده پیش‌فرض از struct، کلاس‌ها در چند سناریوی خاص ضروری هستند. هر کدام را با مثال‌های عملی بررسی می‌کنیم.

کامپوننت‌های UIKit و AppKit

همه کامپوننت‌های UI در iOS و macOS کلاس‌هایی هستند که از UIView (iOS) یا NSView (macOS) ارث می‌برند. شما نمی‌توانید UIViewController را با struct جایگزین کنید — به وراثت و deinit برای آزادسازی منابع نیاز دارد. هنگام کار با UIKit از کلاس‌ها برای کنترلرها، viewها و delegateهای آنها استفاده کنید.

Singleton و حالت مشترک

الگوی Singleton (یک نمونه کلاس برای کل برنامه) به معناشناسی ارجاعی نیاز دارد. مدیران: NetworkManager, SettingsManager, AnalyticsService — معمولاً به عنوان کلاس‌هایی با shared static property پیاده‌سازی می‌شوند. ساختارها مناسب نیستند زیرا هر کپی یک نمونه مستقل خواهد بود.

Dependency Injection و اشیاء ارجاعی

وقتی یک شیء باید تنها منبع حقیقت (single source of truth) باشد و بین ماژول‌ها با ارجاع منتقل می‌شود — از class استفاده کنید. این مربوط به مدیریت حالتی است که تغییر شیء در یک مکان باید در همه کامپوننت‌های وابسته قابل مشاهده باشد. برای ObservableObject در SwiftUI کلاس‌ها اجباری هستند.

swift
// ObservableObject — class لازم برای SwiftUI
import SwiftUI

class AppViewModel: ObservableObject {
    @Published var isLoggedIn: Bool = false
    @Published var username: String = ""

    func login(user: String) {
        isLoggedIn = true
        username = user
    }
}

// استفاده در نمای SwiftUI
struct ContentView: View {
    @StateObject var viewModel = AppViewModel()

    var body: some View {
        Text(viewModel.isLoggedIn ? "خوش آمدید" : "ورود")
    }
}

قاعده: اگر شیء باید هویت داشته باشد (دو ارجاع -> یک شیء)، یک نمونه منحصر به فرد باشد یا با UIKit/Objective-C کار کند — class را انتخاب کنید. اگر شیء فقط داده ذخیره می‌کند — struct را انتخاب کنید.

سوالات متداول

class در Swift چیست؟

Class — یک نوع ارجاعی (reference type) در Swift است که از وراثت، مقدارزدایی و ARC برای مدیریت حافظه پشتیبانی می‌کند. نمونه‌های کلاس‌ها در heap ذخیره می‌شوند و متغیرها حاوی ارجاع به شیء هستند، نه کپی آن.

class چه تفاوتی با struct در Swift دارد؟

Class — reference type (با ارجاع منتقل می‌شود)، از وراثت و deinit پشتیبانی می‌کند. Struct — value type (کپی می‌شود)، از وراثت پشتیبانی نمی‌کند اما پروتکل‌ها را پیاده‌سازی می‌کند و memberwise init را به طور خودکار دریافت می‌کند. Swift struct را به عنوان نوع پیش‌فرض توصیه می‌کند.

ARC در Swift چیست؟

ARC (Automatic Reference Counting) — مکانیزم مدیریت حافظه برای کلاس‌های Swift. هر نمونه یک شمارنده ارجاع قوی دارد. وقتی شمارنده به صفر می‌رسد حافظه آزاد می‌شود. ارجاعات weak و unowned از چرخه‌های ارجاع قوی بین اشیاء جلوگیری می‌کنند.

deinit در Swift چیست؟

Deinit — متد کلاس که به طور خودکار قبل از آزادسازی حافظه آن فراخوانی می‌شود. برای بستن فایل‌ها، لغو اشتراک اعلان‌ها و سایر عملیات پایانی استفاده می‌شود. Deinit فقط در کلاس‌ها وجود دارد — ساختارها آن را ندارند.

چه زمانی از class در Swift استفاده کنیم؟

از class برای کامپوننت‌های UI UIKit/AppKit، singleton، ObservableObject در SwiftUI، اشیاء با هویت مشترک (delegate, observer) و هنگام کار با Objective-C runtime استفاده کنید. برای مدل‌های داده، DTO و تنظیمات struct ترجیح داده می‌شود.

خلاصه

  • Class — reference type در Swift با معناشناسی انتقال با ارجاع: همه متغیرهایی که به یک شیء اشاره می‌کنند وضعیت فعلی آن را می‌بینند و می‌توانند آن را تغییر دهند.
  • ARC حافظه کلاس‌ها را از طریق شمارش ارجاع قوی مدیریت می‌کند؛ weak و unowned از چرخه‌های ارجاع در parent-child و بسته‌ها جلوگیری می‌کنند.
  • وراثت به کلاس‌ها امکان استفاده مجدد و بازنویسی رفتار والد را می‌دهد، اما سلسله‌مراتب عمیق (5+ سطح) نگهداری کد را دشوار می‌کند.
  • Deinit هنگام آزادسازی شیء اجرا می‌شود و برای آزادسازی منابع — فایل‌ها، تایمرها، اشتراک‌های NotificationCenter — الزامی است.
  • UIKit و AppKit برای همه کامپوننت‌های UI به کلاس‌ها نیاز دارند — UIView, UIViewController, delegateها و data sourceهای آنها.
  • ObservableObject در SwiftUI — class اجباری است، زیرا SwiftUI تغییرات را از طریق @Published و @StateObject با ارجاع ردیابی می‌کند.
  • اپل struct را به عنوان نوع پیش‌فرض برای انواع داده جدید توصیه می‌کند — فقط زمانی از class استفاده کنید که هویت، وراثت یا یکپارچه‌سازی با Objective-C مورد نیاز باشد.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید