http://stackoverflow.com/questions/40501780/examples-of-delegates-in-swift-3
So why should I use delegation instead of those options?
I will try to make it simple; You should use delegation when you have one to one relationship between two objects.
Just to make it clearer, the goal of talking a little bit about the NotificationCenter is to trying to make sense when to use delegations:
NotificationCenter represents one to many relationship. Simply, It works like: posting a notification on a specific event and any object can observe this notification; Logically speaking, that’s what one to many relationship means.
Imagine that you are building an application that related to playing audios, some of viewControllers should have a view of an audio player, in the simplest case, we assume that it should has a play/pause button and let’s say a button for showing a playlist.
In order for the viewController to control all the different audio players, the viewController must have a delegate. That is, it delegates tasks to that “Audio Player”. We create the protocol like so:
1 2 3 4 5 |
// here is the protocol for creating the delegation: protocol AudioPlayerDelegate { func playPauseDidTap() func playlistDidTap() } |
This means that whatever the implementation of the Audio Player is, whether its a mp3 player, or a cloud music cast, or square, or circle, blue, or red, it doesn’t matter. As long as the player conform do this protocol, it can receive control messages from the ViewController. Thus, say we create an audio player called MacAmp, it would be like this:
1 2 3 4 |
class MacAmp <AudioPlayerDelegate> { // properties // features } |
When we would have the delegate property in the View, so that it can control our MacAmp audio player. Notice:
1 |
var delegate:AudioPlayerDelegate? |
Using the delegate in Views to control other audio players (such as MacAmp, that conforms to AudioPlayerDelegate)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class AudioPlayerView: UIView { //MARK:- IBOutlets @IBOutlet weak private var btnPlayPause: UIButton! @IBOutlet weak private var btnPlaylist: UIButton! // MARK:- Delegate weak var delegate:AudioPlayerDelegate? // IBActions @IBAction private func playPauseTapped(_ sender: AnyObject) { delegate?.playPauseDidTap() } @IBAction private func playlistTapped(_ sender: AnyObject) { delegate?.playlistDidTap() } } |
In AudioPlayerView’s implementation file’s viewDidLoad or init method, you’d connect AudioPlayerView’s.
AudioPlayerView.m
1 2 3 4 5 6 7 8 9 10 |
override func viewDidLoad() { super.viewDidLoad() //create instance of the audio player self.player = MacAmp() self.delegate = player } |
then you use it like so elsewhere in AudioPlayerView.m:
1 |
self.delegate.playPauseDidTap(); |
So far so good, the audio player view has its separated UIView class and .xib file, in the wanted viewController you loaded it and added as a subview
But now, how could you add functionality to the both buttons? you might think of: “Simply, I will add an IBAction in the view class and that’s it”, well at the first look, it might sounds ok, but after thinking about it, you will recognize that it is a bad idea if you are trying to handle the event of tapping the button at the controller layer level, in other words, what if each viewController should does a different event for -for example- playlist button? let’s do delegation:
‘weak’ may only be applied to class and class-bound protocol types
https://stackoverflow.com/questions/38841127/why-can-the-keyword-weak-only-be-applied-to-class-and-class-bound-protocol-typ
weak is a qualifier for reference types (as opposed to value types, such as structs and built-in value types).
Reference types let you have multiple references to the same object. The object gets deallocated when the last strong reference stops referencing it (weak references do not count).
Value types, on the other hand, are assigned by copy. Reference counting does not apply, so weak modifier does not make sense with them.
However! One common reason for this error is that you have declared you own protocol, but forgot to inherit from NSObjectProtocol:
1 2 3 4 5 6 7 |
protocol PenguinDelegate: NSObjectProtocol { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? } |
The code above will give you the error if you forget to inherit from NSObjectProtocol.