Protocol — چیست، پروتکل‌ها و دلیگیت‌ها در iOS

نویسنده: IT Sectr منتشر شده: 2026-02-18 زمان مطالعه: 10 دقیقه

Protocol — مجموعه‌ای از الزامات (ویژگی‌ها و متدها) است که تایپ پیاده‌کننده این پروتکل باید از آنها پیروی کند. در Swift، پروتکل‌ها عنصر مرکزی Protocol-Oriented Programming (POP) هستند که پلی‌مورفیسم را بدون وراثت امکان‌پذیر می‌کنند. بر اساس داده‌های Swift.org (2025)، پروتکل‌ها در ۸۵٪ تایپ‌های کتابخانه استاندارد Swift استفاده می‌شوند. در Objective-C، @protocol نقشی مشابه دارد اما با محدودیت — فقط برای کلاس‌ها.

نکات کلیدی

  • Protocol — قراردادی که اینترفیسی را تعریف می‌کند که یک struct، class یا enum باید آن را پیاده‌سازی کند
  • Protocol-Oriented Programming — پارادایم Swift که در آن پروتکل‌ها و توسعه‌دهنده‌های پروتکل جایگزین سلسله‌مراتب عمیق وراثت می‌شوند
  • Protocol extension — پیاده‌سازی پیش‌فرض متدها که متدهای پروتکل را بدون @objc اختیاری می‌کند
  • Associated types — پروتکل‌های عمومی با تایپ‌های مرتبط برای کار type-safe با انواع متفاوت داده
  • Protocol composition — ترکیب چند پروتکل با عملگر & برای توصیف دقیق الزامات

پروتکل در Swift چیست؟

Protocol در Swift — یک اینترفیس انتزاعی است که الزاماتی را که یک تایپ باید برآورده کند تعریف می‌کند. پروتکل می‌تواند ویژگی‌ها (با getter/setter)، متدها (نمونه و تایپ)، مقداردهنده‌ها و subscript را الزام کند. برخلاف کلاس‌ها، پروتکل‌ها می‌توانند توسط structها، enumها و classها پیاده‌سازی شوند — این انعطاف‌پذیری را فراهم می‌کند که در زبان‌های صرفاً کلاس‌محور در دسترس نیست.

Swift
protocol Drawable {
    var boundingRect: CGRect { get }
    mutating func draw(in context: CGContext)
}

struct Circle: Drawable {
    var center: CGPoint
    var radius: CGFloat
    
    var boundingRect: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
    
    func draw(in context: CGContext) {
        context.addEllipse(in: boundingRect)
    }
}

struct Circle پروتکل Drawable را پیاده‌سازی می‌کند و ویژگی boundingRect و متد draw(in:) را ارائه می‌دهد. به لطف پروتکل، هر شکلی که Drawable را پیاده‌سازی کند می‌تواند به صورت یکپارچه پردازش شود — این پلی‌مورفیسم بدون وراثت از یک کلاس پایه مشترک است.

Protocol-Oriented Programming: پارادایم Swift

Protocol-Oriented Programming (POP) — پارادایمی است که توسط Apple در WWDC 2015 به عنوان جایگزینی برای وراثت کلاسی ارائه شد. در POP، پروتکل‌ها ابزار اصلی انتزاع هستند و توسعه‌دهنده‌های پروتکل (protocol extensions) پیاده‌سازی پیش‌فرض را ارائه می‌دهند. این کار مشکل «وراثت لوزی» را حل می‌کند و امکان توسعه تایپ‌های موجود بدون تغییر کد منبع را فراهم می‌کند.

جنبهPOP (Protocol-Oriented)OOP (Class-based)
واحد انتزاعProtocolکلاس پایه
استفاده مجددProtocol extensionوراثت
Value typesپشتیبانی می‌شود (struct)فقط reference types
کاربرد چندگانهProtocol compositionوراثت چندگانه (نه در Swift)
ریسک وابستگیکم (اتصال ضعیف)زیاد (سلسله‌مراتب سفت و سخت)

بر اساس وبلاگ Apple Swift (2025)، structها ۷۰٪ تایپ‌ها را در برنامه‌های مدرن Swift تشکیل می‌دهند. POP دلیل اصلی این تغییر است: پروتکل‌ها به structها اجازه می‌دهند بدون انتقال به کلاس‌ها رفتار پلی‌مورفیک داشته باشند.

Protocol vs abstract class vs interface

پروتکل‌های Swift موقعیت میانی بین اینترفیس‌های Java و کلاس‌های انتزاعی C++ را اشغال می‌کنند. آنها می‌توانند پیاده‌سازی داشته باشند (از طریق extension)، اما حالت (ویژگی‌های ذخیره‌شده) ندارند. تفاوت‌ها را با مثال سه زبان بررسی می‌کنیم.

ویژگیSwift ProtocolJava InterfaceC++ Abstract Class
پیاده‌سازی متدهابله (extension)بله (default methods)بله
ویژگی‌های ذخیره‌شدهخیرخیربله
Value typesبلهخیرخیر
پیاده‌سازی چندگانهبلهبلهبله
مقداردهنده‌هابله (الزامات)خیربله

تفاوت کلیدی: Swift Protocol می‌تواند مقداردهنده‌ها و subscript را الزام کند که در Java Interface در دسترس نیست. در عین حال پروتکل نمی‌تواند حالت را ذخیره کند — این وظیفه تایپ پیاده‌کننده پروتکل است.

Associated Types و Generics در پروتکل‌ها

Associated Type (تایپ مرتبط) — یک تایپ عمومی درون پروتکل است که توسط تایپ پیاده‌کننده مشخص می‌شود. این امکان ایجاد پروتکل‌های type-safe را بدون تعیین تایپ داده خاص فراهم می‌کند. تایپ‌های مرتبط با جنریک‌های Swift کار می‌کنند.

Swift
protocol Container {
    associatedtype Item
    var count: Int { get }
    mutating func append(_ item: Item)
    subscript(i: Int) -> Item { get }
}

struct IntStack: Container {
    var items: [Int] = []
    var count: Int { items.count }
    typealias Item = Int
    
    mutating func append(_ item: Int) {
        items.append(item)
    }
    
    subscript(i: Int) -> Int {
        items[i]
    }
}

func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
    // بدنه تابع
}

Container — پروتکلی با associatedtype Item. IntStack آن را پیاده‌سازی می‌کند و typealias Item = Int را مشخص می‌کند. تابع جنریک sum از where-محدودیت برای کار فقط با کانتینرهای عددی استفاده می‌کند. Associated types پروتکل‌ها را بدون از دست دادن type-safety عمومی می‌کنند.

Protocol composition و توسعه‌دهنده‌های پروتکل

Protocol composition — ترکیب چند پروتکل با عملگر &. تایپ منطبق بر ترکیب باید تمام پروتکل‌های ترکیب‌شده را پیاده‌سازی کند. این جایگزین وراثت چندگانه می‌شود که در Swift وجود ندارد و امکان مشخص کردن دقیق الزامات پارامترهای تابع را فراهم می‌کند.

Swift
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }

struct Person: Named, Aged {
    let name: String
    let age: Int
}

func greet(_ entity: Named & Aged) {
    print("سلام، \(entity.name)، سن \(entity.age)!")
}

// Protocol extension — پیاده‌سازی پیش‌فرض
extension Named {
    func introduce() {
        print("اسم من \(name)")
    }
}

Protocol extension پیاده‌سازی پیش‌فرض متدها را فراهم می‌کند. تایپ پیاده‌کننده پروتکل می‌تواند متد extension را بازنویسی کند — در این صورت پیاده‌سازی خودش فراخوانی می‌شود. این مکانیزمی است که Swift با آن متدهای اختیاری را بدون @objc پیاده‌سازی می‌کند.

@protocol در Objective-C: تفاوت‌ها با Swift

@protocol در Objective-C — predecessor پروتکل Swift است، اما با محدودیت‌های قابل توجه. پروتکل‌های Objective-C فقط برای کلاس‌ها در دسترس هستند (نه برای structها یا enumها) و از ارسال پویا از طریق message passing استفاده می‌کنند. متدها می‌توانند @required (پیش‌فرض) یا @optional باشند.

Objective-C
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end

@interface ConsoleLogger : NSObject 
@end

@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
    NSLog(@"[LOG] %@", message);
}
@end

برخلاف Swift، پروتکل‌های Objective-C از associated types, generics, protocol extensions و value types پشتیبانی نمی‌کنند. آنها مکانیزم انتزاع کلاسی باقی می‌مانند، در حالی که Swift Protocol یک ابزار تمام‌عیار پلی‌مورفیسم برای همه تایپ‌ها است.

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

تفاوت پروتکل با کلاس انتزاعی چیست؟

Protocol نمی‌تواند حالت (ویژگی‌های ذخیره‌شده) را نگه دارد — فقط الزامات مربوط به ویژگی‌ها. Abstract class می‌تواند فیلدهای دارای داده داشته باشد. Protocol می‌تواند توسط structها و enumها پیاده‌سازی شود، abstract class — فقط توسط کلاس‌ها. در Swift پروتکل‌ها ابزار اصلی انتزاع هستند، کلاس‌ها کمتر استفاده می‌شوند.

Protocol-Oriented Programming چیست؟

POP — پارادایمی که در آن پروتکل‌ها و توسعه‌دهنده‌های پروتکل جایگزین سلسله‌مراتب عمیق وراثت می‌شوند. به جای کلاس پایه‌ای که همه زیرکلاس‌ها از آن ارث می‌برند، POP از ترکیب پروتکل‌ها با پیاده‌سازی‌های پیش‌فرض از طریق extension استفاده می‌کند. این کار وابستگی را کاهش داده و استفاده مجدد از کد را افزایش می‌دهد.

آیا پروتکل می‌تواند از پروتکل دیگری ارث‌بری کند؟

بله، پروتکل‌های Swift از وراثت پشتیبانی می‌کنند. protocol SerializableDrawable: Drawable, Codable — پروتکلی که الزامات Drawable و Codable را ترکیب می‌کند. تایپ پیاده‌کننده SerializableDrawable باید الزامات همه پروتکل‌های سلسله‌مراتب را برآورده کند. این با وراثت کلاس متفاوت است — پروتکل‌ها جد مشترکی ندارند.

any و some در زمینه پروتکل‌ها چیستند؟

some (opaque type) تضمین می‌کند که تابع یک تایپ خاص منطبق بر پروتکل را برمی‌گرداند. any (existential type) امکان ذخیره هر تایپ منطبق بر پروتکل را فراهم می‌کند. some برای حفظ هویت تایپ استفاده می‌شود، any — برای مجموعه‌های ناهمگن. some در Swift 5.1 ظاهر شد، any — در Swift 5.7.

چگونه مطابقت با پروتکل را در Swift بررسی کنیم؟

از is برای بررسی و as? برای تبدیل استفاده کنید: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. در Objective-C از conformsToProtocol: استفاده می‌شود. Swift همچنین is-بررسی را برای پروتکل‌های بدون associated types پشتیبانی می‌کند.

خلاصه

  • Protocol — قراردادی که الزامات مربوط به ویژگی‌ها، متدها، مقداردهنده‌ها و subscript را برای تایپ پیاده‌کننده تعریف می‌کند
  • Protocol-Oriented Programming وراثت کلاسی را با ترکیب پروتکل‌ها با توسعه‌دهنده‌ها جایگزین می‌کند
  • Protocol extension پیاده‌سازی پیش‌فرض را فراهم کرده، متدها را بدون @objc اختیاری می‌کند
  • Associated types امکان ایجاد پروتکل‌های عمومی با مشخص شدن تایپ در سمت پیاده‌سازی را فراهم می‌کند
  • Protocol composition از طریق & الزامات چند پروتکل را ترکیب می‌کند
  • Objective-C @protocol به کلاس‌ها محدود است و از associated types, generics و value types پشتیبانی نمی‌کند
  • توصیه: از پروتکل‌ها به عنوان ابزار اصلی انتزاع در Swift استفاده کنید، کلاس‌ها را فقط در صورت نیاز به reference semantics به کار ببرید

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

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

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

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