ios - كيفية تحديد الطرق الاختيارية في بروتوكول سويفت؟




swift swift-protocols (10)

أعتقد أنه قبل السؤال كيف يمكنك تنفيذ طريقة بروتوكول اختيارية ، يجب أن تسأل لماذا يجب عليك تنفيذ أحدها.

إذا فكرنا في بروتوكولات سريعة كواجهة في البرمجة الكلاسيكية الموجهة للكائنات ، فإن الأساليب الاختيارية ليست منطقية ، وربما يكون الحل الأفضل هو إنشاء تطبيق افتراضي ، أو فصل البروتوكول إلى مجموعة من البروتوكولات (ربما مع بعض علاقات الوراثة). بينهما) لتمثيل مجموعة ممكنة من الأساليب في البروتوكول.

لمزيد من القراءة ، راجع https://useyourloaf.com/blog/swift-optional-protocol-methods/ ، الذي يقدم نظرة عامة ممتازة حول هذه المسألة.

هل من الممكن في سويفت؟ إذا لم يكن هناك حل بديل للقيام بذلك؟


إذا كنت تريد أن تفعل ذلك في swift pure فإن أفضل طريقة هي توفير تطبيق افتراضي خاص إذا قمت بإرجاع نوع Swift مثل البنية على سبيل المثال مع أنواع Swift

مثال:

struct magicDatas {
    var damagePoints : Int?
    var manaPoints : Int?
}

protocol magicCastDelegate {
    func castFire() -> magicDatas
    func castIce() -> magicDatas
}

extension magicCastDelegate {
    func castFire() -> magicDatas {
        return magicDatas()
    }

    func castIce() -> magicDatas {
        return magicDatas()
    }
}

ثم يمكنك تنفيذ البروتوكول دون تعريف كل func


خارج الموضوع من السؤال الأصلي ، لكنه يبني فكرة أنطوان واعتقدت أنه قد يساعد شخص ما.

يمكنك أيضًا جعل الخصائص المحسوبة اختيارية للبنيات ذات امتدادات البروتوكول.

يمكنك جعل خاصية على البروتوكول اختياري

protocol SomeProtocol {
    var required: String { get }
    var optional: String? { get }
}

تطبيق الخاصية المحسوبة الوهمية في ملحق البروتوكول

extension SomeProtocol {
    var optional: String? { return nil }
}

والآن يمكنك استخدام البنى التي تنفذ أو لا تنفذ الخاصية الاختيارية

struct ConformsWithoutOptional {
    let required: String
}

struct ConformsWithOptional {
    let required: String
    let optional: String?
}

لقد قمت أيضًا بكتابة كيفية القيام بخصائص اختيارية في بروتوكولات Swift على مدونتي ، والتي سوف يتم تحديثها في حالة تغير الأشياء من خلال إصدارات Swift 2.


ضع @optional أمام الطرق أو الخصائص.


في Swift 3.0

@objc protocol CounterDataSource {
    @objc optional func increment(forCount count: Int) -> Int
    @objc optional var fixedIncrement: Int { get }
}

سيوفر وقتك.


في Swift 2.0 ، من الممكن إضافة تطبيقات افتراضية للبروتوكول. هذا يخلق طريقة جديدة للطرق الاختيارية في البروتوكولات.

protocol MyProtocol {
    func doSomethingNonOptionalMethod()
    func doSomethingOptionalMethod()
}

extension MyProtocol {
    func doSomethingOptionalMethod(){ 
        // leaving this empty 
    }
}

إنها ليست طريقة لطيفة في إنشاء طرق بروتوكول اختيارية ، ولكنها تمنحك إمكانية استخدام البنى في عمليات استدعاء البروتوكول.

كتبت ملخصًا صغيرًا هنا: http://www.avanderlee.com/swift-2-0/optional-protocol-methods/


لتوضيح آليات إجابة Antoine:

protocol SomeProtocol {
    func aMethod()
}

extension SomeProtocol {
    func aMethod() {
        print("extensionImplementation")
    }
}

class protocolImplementingObject: SomeProtocol {

}

class protocolImplementingMethodOverridingObject: SomeProtocol {
    func aMethod() {
        print("classImplementation")
    }
}

let noOverride = protocolImplementingObject()
let override = protocolImplementingMethodOverridingObject()

noOverride.aMethod() //prints "extensionImplementation"
override.aMethod() //prints "classImplementation"

نظرًا لوجود بعض الإجابات حول كيفية استخدام أداة التعديل الاختيارية والسمةobjc لتحديد بروتوكول المتطلبات الاختيارية ، فسوف أعطي عينة حول كيفية استخدام إضافات البروتوكول لتعريف البروتوكول الاختياري.

الرمز أدناه هو Swift 3. *.

/// Protocol has empty default implementation of the following methods making them optional to implement:
/// `cancel()`
protocol Cancelable {

    /// default implementation is empty.
    func cancel()
}

extension Cancelable {

    func cancel() {}
}

class Plane: Cancelable {
  //Since cancel() have default implementation, that is optional to class Plane
}

let plane = Plane()
plane.cancel()
// Print out *United Airlines can't cancelable*

يرجى ملاحظة أن طرق تمديد البروتوكول لا يمكن استدعاؤها بواسطة كود Objective-C ، والأسوأ من ذلك هو أن فريق سويفت لن يصلحها. https://bugs.swift.org/browse/SR-492


هنا مثال ملموس بنمط التفويض.

إعداد البروتوكول الخاص بك:

@objc protocol MyProtocol:class
{
    func requiredMethod()
    optional func optionalMethod()
}

class MyClass: NSObject
{
    weak var delegate:MyProtocol?

    func callDelegate()
    {
        delegate?.requiredMethod()
        delegate?.optionalMethod?()
    }
}

تعيين المفوض إلى فئة وتنفيذ البروتوكول. انظر أن الطريقة الاختيارية لا تحتاج إلى التنفيذ.

class AnotherClass: NSObject, MyProtocol
{
    init()
    {
        super.init()

        let myInstance = MyClass()
        myInstance.delegate = self
    }

    func requiredMethod()
    {
    }
}

شيء واحد مهم هو أن الطريقة الاختيارية اختيارية وتحتاج إلى "؟" عند الاتصال. اذكر علامة الاستفهام الثانية.

delegate?.optionalMethod?()

إذا كنت ترغب في استخدام طرق اختيارية ، يجب عليك وضع علامة على البروتوكول الخاص بك باستخدام سمة @objc :

@objc protocol MyProtocol {

    @objc optional func doSomething()

}

class MyClass : MyProtocol {

    // no error

}

خلاف ذلك ، تتصرف بروتوكولات Swift مثل واجهات على لغات OO الأخرى ، حيث يجب تنفيذ جميع الطرق المعرفة في الواجهات.







swift-extensions