Protocol — ما هو، البروتوكولات والمفوّضون في iOS

المؤلف: IT Sectr نُشر: 2026-02-18 وقت القراءة: 10 دق

Protocol هو مجموعة من المتطلبات (الخصائص والطرق) التي يجب أن يفي بها النوع الذي يتبنى البروتوكول. في Swift، البروتوكولات هي العنصر المركزي في البرمجة الموجهة بالبروتوكولات (POP)، مما يتيح تعدد الأشكال دون وراثة. وفقًا لـ Swift.org (2025)، تُستخدم البروتوكولات في 85% من أنواع المكتبة القياسية لـ Swift. في Objective-C، يؤدي @protocol دورًا مشابهًا، ولكن مع قيد — فقط للفئات.

الخلاصة

  • Protocol — عقد يحدد الواجهة التي يجب أن تنفذها البنية أو الفئة أو التعداد
  • البرمجة الموجهة بالبروتوكولات — نموذج Swift حيث تحل البروتوكولات وامتدادات البروتوكول محل التسلسل الهرمي العميق للوراثة
  • امتداد البروتوكول — تطبيقات افتراضية للطرق، مما يجعل طرق البروتوكول اختيارية بدون @objc
  • الأنواع المرتبطة — بروتوكولات عامة مع أنواع مرتبطة للعمل الآمن مع أنواع مختلفة من البيانات
  • تكوين البروتوكول — دمج عدة بروتوكولات عبر عامل التشغيل & لتحديد دقيق للمتطلبات

ما هو البروتوكول في Swift؟

Protocol في Swift هو واجهة مجردة تحدد المتطلبات التي يجب أن يفي بها النوع. يمكن للبروتوكول أن يطلب خصائص (مع getter/setter)، وطرق (للنسخة وللنوع)، ومهيئات، ومخطوطات فرعية. على عكس الفئات، يمكن تبني البروتوكولات بواسطة البنى والتعدادات والفئات — مما يوفر مرونة غير متوفرة في اللغات القائمة على الفئات فقط.

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)
    }
}

البنية Circle تتبنى بروتوكول Drawable، موفرة الخاصية boundingRect والطريقة draw(in:). بفضل البروتوكول، يمكن معالجة أي شكل يطبق Drawable بشكل موحد — هذا هو تعدد الأشكال دون وراثة من فئة أساسية مشتركة.

البرمجة الموجهة بالبروتوكولات: نموذج Swift

البرمجة الموجهة بالبروتوكولات (POP) هي نموذج قدمته Apple في WWDC 2015 كبديل للوراثة القائمة على الفئات. في POP، البروتوكولات هي أداة التجريد الرئيسية وامتدادات البروتوكول توفر تطبيقات افتراضية. هذا يحل مشكلة «وراثة الماس» ويسمح بتوسيع الأنواع الموجودة دون تعديل الكود المصدري.

الجانبPOP (موجه بالبروتوكولات)OOP (قائم على الفئات)
وحدة التجريدProtocolفئة أساسية
آلية إعادة الاستخدامامتداد البروتوكولالوراثة
أنواع القيمةمدعومة (struct)أنواع المرجع فقط
التبني المتعددتكوين البروتوكولالوراثة المتعددة (ليس في Swift)
خطر الاقترانمنخفض (اقتران ضعيف)مرتفع (تسلسل هرمي صلب)

وفقًا لمدونة Apple Swift (2025)، تشكل البنى 70% من الأنواع في تطبيقات Swift الحديثة. POP هو سبب رئيسي لهذا التحول: البروتوكولات تسمح للبنى بالحصول على سلوك متعدد الأشكال دون الانتقال إلى الفئات.

البروتوكول مقابل الفئة المجردة مقابل الواجهة

بروتوكولات Swift تحتل موقعًا وسطًا بين واجهات Java والفئات المجردة في C++. يمكنها احتواء تطبيقات (عبر الامتدادات) لكن لا يمكنها امتلاك حالة (خصائص مخزنة). دعنا نفحص الاختلافات عبر ثلاث لغات.

الخاصيةSwift ProtocolJava InterfaceC++ Abstract Class
تطبيق الطرقنعم (extension)نعم (طرق افتراضية)نعم
خصائص مخزنةلالانعم
أنواع القيمةنعملالا
تطبيق متعددنعمنعمنعم
مهيئاتنعم (متطلبات)لانعم

الفرق الرئيسي: Swift Protocol يمكنه طلب مهيئات ومخطوطات فرعية، وهو غير متوفر في Java Interface. ومع ذلك، لا يمكن للبروتوكول تخزين حالة — وهذا يبقى مسؤولية النوع الذي يتبنى البروتوكول.

الأنواع المرتبطة والأدوية العامة في البروتوكولات

النوع المرتبط (Associated Type) هو نوع عام داخل بروتوكول يتم تجسيده بواسطة النوع المتبني. هذا يسمح بإنشاء بروتوكولات آمنة النوع دون تحديد نوع بيانات محدد. تعمل الأنواع المرتبطة جنبًا إلى جنب مع الأدوية العامة في 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 للعمل فقط مع الحاويات الرقمية. الأنواع المرتبطة تجعل البروتوكولات عامة دون فقدان أمان النوع.

تكوين البروتوكول وامتدادات البروتوكول

تكوين البروتوكول — دمج عدة بروتوكولات عبر عامل التشغيل &. النوع المتوافق مع التكوين يجب أن ينفذ جميع البروتوكولات المدمجة. هذا يستبدل الوراثة المتعددة، الغائبة في 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)!")
}

// امتداد البروتوكول — تطبيق افتراضي
extension Named {
    func introduce() {
        print("اسمي \(name)")
    }
}

امتداد البروتوكول يوفر تطبيقات افتراضية للطرق. النوع الذي يتبنى البروتوكول يمكنه تجاوز طريقة الامتداد — في هذه الحالة، يتم استدعاء تطبيقه الخاص. هذه هي الآلية التي ينفذ بها Swift الطرق الاختيارية دون @objc.

@protocol في Objective-C: الاختلافات عن Swift

@protocol في Objective-C هو سلف Swift Protocol، ولكن مع قيود كبيرة. بروتوكولات Objective-C متاحة فقط للفئات (ليس للبنى أو التعدادات) وتستخدم الإرسال الديناميكي عبر تمرير الرسائل. يمكن أن تكون الطرق @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 لا تدعم الأنواع المرتبطة أو الأدوية العامة أو امتدادات البروتوكول أو أنواع القيمة. تبقى آلية تجريد قائمة على الفئات، بينما Swift Protocol هي أداة تعدد أشكال كاملة لجميع الأنواع.

الأسئلة الشائعة

كيف يختلف البروتوكول عن الفئة المجردة؟

البروتوكول لا يمكنه تخزين حالة (خصائص مخزنة) — فقط متطلبات الخصائص. الفئة المجردة يمكنها احتواء حقول بيانات. البروتوكول يمكن تبنيه بواسطة البنى والتعدادات، بينما الفئة المجردة يمكن توريثها فقط بواسطة الفئات. في Swift، البروتوكولات هي أداة التجريد الرئيسية؛ الفئات تستخدم بشكل أقل.

ما هي البرمجة الموجهة بالبروتوكولات؟

POP هو نموذج حيث تحل البروتوكولات وامتدادات البروتوكول محل التسلسلات الهرمية العميقة للوراثة. بدلاً من فئة أساسية ترث منها جميع الفئات الفرعية، يستخدم POP تكوين البروتوكولات مع تطبيقات افتراضية عبر الامتداد. هذا يقلل الاقتران ويحسن إعادة استخدام الكود.

هل يمكن للبروتوكول أن يرث بروتوكولًا آخر؟

نعم، بروتوكولات Swift تدعم الوراثة. protocol SerializableDrawable: Drawable, Codable — بروتوكول يجمع متطلبات Drawable و Codable. النوع الذي يتبنى SerializableDrawable يجب أن يفي بمتطلبات جميع البروتوكولات في التسلسل الهرمي. هذا يختلف عن وراثة الفئات — البروتوكولات ليس لها سلف مشترك.

ما هما any و some في سياق البروتوكولات؟

some (نوع معتم) يضمن أن الدالة ترجع نوعًا واحدًا محددًا يتوافق مع البروتوكول. any (نوع وجودي) يسمح بتخزين أي نوع يتوافق مع البروتوكول. 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 للبروتوكولات بدون أنواع مرتبطة.

الملخص

  • Protocol — عقد يحدد متطلبات الخصائص والطرق والمهيئات والمخطوطات الفرعية للنوع المتبني
  • البرمجة الموجهة بالبروتوكولات تستبدل وراثة الفئات بتكوين البروتوكولات والامتدادات
  • امتداد البروتوكول يوفر تطبيقات افتراضية، مما يجعل الطرق اختيارية بدون @objc
  • الأنواع المرتبطة تسمح بإنشاء بروتوكولات عامة مع تجسيد النوع في جانب التنفيذ
  • تكوين البروتوكول عبر & يجمع متطلبات عدة بروتوكولات
  • Objective-C @protocol محدود بالفئات ولا يدعم الأنواع المرتبطة أو الأدوية العامة أو أنواع القيمة
  • توصية: استخدم البروتوكولات كأداة تجريد رئيسية في Swift، مع اللجوء إلى الفئات فقط عند الحاجة إلى دلالات المرجع

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا