Today, in this article I will share with everyone 2 ways to make protocol optional
, according to which are its advantages and disadvantages.
Default Implement
The first way is to create an extension
of the protocol
and then initialize an empty method on that protocol
.
1 2 3 4 5 6 7 8 9 10 11 12 13 | import Foundation protocol PickerViewDelegate { func didChooseItem(at index: Int) // Required func didDismiss() // Optional } extension PickerViewDelegate { func didDismiss() { // Do nothing. } } |
With this approach didDismiss()
would be an optional
type. Now let’s try conform PickerViewDelegate
to a class.
1 2 3 4 5 6 | class Controller: PickerViewDelegate { func didChooseItem(at index: Int) { } } |
Well, complier doesn’t require us to install the didDismiss()
Advantages:
- We can conform constructs to a
protocol
- The default setting inside the
extension
will automatically be used when we don’t implement that method inconforming
style
Disadvantages:
- In the case when an
optional
method returns anon-void
value, we will need to catch up and return the value inside the default setting.
Objective-C ‘optional’ Keyword
Highlight the protocol with @objc
and optional
method with @objc optional/ optional
:
1 2 3 4 5 | @objc protocol PickerViewDelegate { func didChooseItem(at index: Int) // Required @objc optional func didDismiss() // Optional } |
With this approach, we don’t need to create an extension, just conform a class with that protocol:
1 2 3 4 5 6 | class Controller: PickerViewDelegate { func didChooseItem(at index: Int) { } } |
With this approach, I believe that everyone encounters it every day but may not notice, that’s when we conform protocol
UICollectionViewDatasource
. When looking at the codebase of UICollectionViewDatasource
, we can see that except for numberOfItemsInSection
and cellForItemAt
, the other methods have key word optional
at the beginning, so when conforming UICollectionViewDatasource, we must initialize the above two methods:
1 2 3 4 5 6 7 8 9 10 11 12 | public protocol UICollectionViewDataSource : NSObjectProtocol { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell optional func numberOfSections(in collectionView: UICollectionView) -> Int optional func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView ... } |
Advantages:
- No need to create extensions
Disadvantages:
- Only
NSObject
subclass
can inherit from a@objc
protocol. This means we cannotconform
structs
orenums
to theprotocol
. - If suddenly we need to call an optional method then we must add
?
or!
after each method’s name (in case weforce
unwrap
and the method is not installed, the app will crash):
1 2 3 4 5 6 7 8 | class PickerView { weak var delegate: PickerViewDelegate? deinit { delegate?.didDismiss?() } } |
Conclude:
Although the second way looks cleaner, I recommend everyone to use the first because it’s flexible. Today’s post has ended, hope everyone can know something from here.
Thank you for reading!
Reference : https://medium.com/better-programming/2-ways-to-make-protocol-methods-optional-in-swift-f032836a343b