[Swift] - Swift로 프로토콜 메서드를 Optional(선택적으로 구현하게)로 만드는 두 가지 방법
프로토콜의 메서드를 Optional로 만드는 두 가지 방법에 대해 알아보자.
https://betterprogramming.pub/2-ways-to-make-protocol-methods-optional-in-swift-f032836a343b
이 글에서는 프로토콜의 메서드를 Optional로 만드는 두 가지 방법에 대해 알아볼 것이다. 그리고 각 방법의 장단점에 대해서도 알아볼 것이다. 참고로 여기에서 말한 optional은 메서드를 필수적으로 구현하는 것이 아닌 선택적으로 구현할 수 있다는 의미에서의 옵셔널을 의미한다.
기본 구현
첫 번째 방법은 프로토콜의 extension을 생성하고 프로토콜의 빈 메서드를 포함시키는 것이다.
import Foundation
protocol PickerViewDelegate {
func didChooseItem(at index: Int) // Required
func didDismiss() // Optional
}
extension PickerViewDelegate {
func didDismiss() {
// Do nothing.
}
}
이 방법으로 didDismiss()
메서드를 선택적으로 구현할 수 있게 만들었다. 이제 PickerViewDelegate
프로토콜을 따를 때 어떤 일이 일어나는지를 확인할 것이다.
class Controller: PickerViewDelegate {
func didChooseItem(at index: Int) {
}
}
보다싶이, 컴파일러가 didDismiss()
메서드를 구현하는 것을 요구하지 않는다.
장점
- 구조체가 프로토콜을 따르게 할 수 있다.
- 우리가 프로토콜을 따르는 타입 안에서 메서드를 구현하지 않을 때, extension에 구현된 내용이 자동으로 사용된다.
단점
- 이 옵셔널 메서드가
void
가 아닌 값을 리턴하면, 기본 구현에서 특정 값을 생각해서 리턴해야 한다.
Objective-C ‘optional’ 키워드
우리는 프로토콜을 @objc
키워드로 마크하고, @objc optional
로 옵셔널 메서드를 표시할 수 있다.
@objc protocol PickerViewDelegate {
func didChooseItem(at index: Int) // Required
@objc optional func didDismiss() // Optional
}
이 방법을 사용하면, extension을 만들 필요가 없다. 단지 프로토콜을 다르게 클래스를 만들면 된다.
class Controller: PickerViewDelegate {
func didChooseItem(at index: Int) {
}
}
장점
- Extension을 만들 필요가 없다.
단점
- 오로지
NSObject
의 하위 클래스만이@objc
프로토콜을 채택할 수 있다. 이 말은 구조체나 열거형이 프로토콜을 따르게 할 수 없다는 것이다. - 만약 optional 메서드를 호출해야 한다면, 꼭 메서드의 이름 뒤에
?
나!
를 붙여줘야 한다.(만약 메서드가 구현되지 않았는데 언래핑을 강행한다면 앱에서 크래시가 날 것이다.)
class PickerView {
weak var delegate: PickerViewDelegate?
deinit {
delegate?.didDismiss?()
}
}