Protocol-delegate is a common pattern in Cocoa development. It links up a lot of part in Cocoa framework, and does a great contribution in decoupling the component in the framework.

In ARC, we always declare a delegate as weak. When the object of this delegate gets released, it will be set to nil. This guarantees even the delegate object destroyed. We would not get a crash when accessing the object. This is a great feature in ARC to reduce the crash rate for an app. If you have experience on MRC, you might remember the nightmare of BAD_EXEC error.

We also want it in Swift! But when we try to write a protocol like this, we will get a compiler complaint:

protocol MyClassDelegate {
    func method()
}

class MyClass {
    weak var delegate: MyClassDelegate?
}

class ViewController: UIViewController, MyClassDelegate {
    // ...
    var someInstance: MyClass!

    override func viewDidLoad() {
        super.viewDidLoad()

        someInstance = MyClass()
        someInstance.delegate = self
    }

    func method() {
        print("Do something")
    }

    //...
}

// weak var delegate: MyClassDelegate? Compile error
// 'weak' cannot be applied to non-class type 'MyClassDelegate'

This is because protocol in Swift could be conformed by instance of any type. For instances struct or enum, they are value instead of reference, there are no concept like reference count on them, so it does not make sense to modify them with keywords like "weak", which is an ARC concept.

If you want to use weak delegate in Swift, you have to restrict the protocol to class type. One way is to declare this protocol belonging to Objective-C. This could be done by adding @objc keyword. The Objective-C protocol could only be conformed by class, so it could be modified with weak as a result:

@objc protocol MyClassDelegate {
    func method()
}

Another approach would be better in my opinion: just add class after the name of protocol. This explicitly points out this protocol could be only conformed by class. Compared to the @objc way, adding class could represent what matters better. It avoids unnecessary interoperating between Swift and Objective-C as well.

protocol MyClassDelegate: class {
    func method()
}