TIL: 프로토콜의 선택적 요구사항의 구현

Royce·2025년 3월 29일

Swift 문법

목록 보기
51/63

선택적 요구사항의 구현 (Optional Protocol Requirements)

  • Swift에서는 프로토콜을 정의할 때, 선택적으로 구현할 수 있는 요구 사항을 선언할 수 있다
  • 이를 활용하면 객체가 필요할 때만 특정 기능을 구현하도록 할 수 있다

어트리뷰트 (Attributes)

  • Swift에서 어트리뷰트(Attribute) 는 컴파일러에게 특정 정보를 제공하는 키워드이다
  • 특정 선언이나 타입에 추가적인 정보 또는 요구 사항을 부여한다

어트리뷰트의 예시

  • @available: 특정 플랫폼이나 버전에서만 사용 가능하도록 지정한다
  • @objc: Objective-C와의 호환성을 위해 사용된다
  • @escaping: 클로저가 함수의 반환 이후에도 사용될 수 있음을 나타낸다
  • @IBOutlet, @IBAction: Interface Builder와의 연결을 나타낸다

어트리뷰트 사용법

@available(iOS 18.0, *)
class ModernFeature {   // iOS 18.0 이상에서만 사용 가능한 클래스 선언
    func useFeature() {
        print("이 기능은 iOS 18.0 이상에서만 사용 가능")  // 조건에 따라 사용 가능
    }
}
  • ModernFeature 클래스는 iOS 18.0 이상에서만 사용 가능하도록 지정되었다
  • @available 어트리뷰트를 이용하여 특정 버전에만 접근 가능하도록 설정할 수 있다

선택적 요구사항의 구현 (Optional Protocol Requirements)

  • Objective-C와의 호환성을 위해 선택적 요구사항을 포함하는 프로토콜을 만들 수 있다
  • 이를 위해 @objc@objc optional을 사용한다

선택적 요구사항을 포함한 프로토콜 정의하기

@objc protocol MusicPlayer {              // Objective-C와의 호환을 위해 @objc 사용
    @objc optional var volume: Int { get set }  // 선택적 속성 (구현할 필요 없음)
    func play()                           // 필수 구현 메서드
    func stop()                           // 필수 구현 메서드
    @objc optional func shuffle()        // 선택적 메서드 (구현할 필요 없음)
}
  • @objc를 사용하면 Objective-C와의 호환성을 갖게 된다
  • @objc optional로 선언된 멤버는 구현해도 되고 하지 않아도 되는 선택적 요구 사항이 된다
  • MusicPlayer 프로토콜을 채택하는 타입은 shuffle() 메서드를 구현하지 않아도 된다

클래스에서 프로토콜을 채택하고 구현하기

class BasicPlayer: MusicPlayer {   // 필수 요구사항만 구현한 클래스
    var volume: Int = 5           // 선택적 속성도 구현할 수 있음
    
    func play() {
        print("음악 재생 중... 볼륨: \(volume)")  // 필수 구현 메서드
    }
    
    func stop() {
        print("음악 정지")  // 필수 구현 메서드
    }
}

class AdvancedPlayer: MusicPlayer {  // 선택적 요구사항도 구현한 클래스
    var volume: Int = 10
    
    func play() {
        print("고급 플레이어에서 음악 재생 중... 볼륨: \(volume)")  
    }
    
    func stop() {
        print("고급 플레이어 음악 정지")  
    }
    
    func shuffle() {   // 선택적 메서드 구현
        print("곡을 무작위로 섞기")  
    }
}
  • BasicPlayer 클래스는 shuffle() 메서드를 구현하지 않았지만 오류 없이 사용 가능하다
  • AdvancedPlayer 클래스는 shuffle() 메서드를 구현하여 추가 기능을 제공한다

선택적 요구사항의 사용과 타입 확인

  • 선택적 요구사항은 프로토콜 타입으로 선언되면 옵셔널 타입으로 인식된다
  • 즉, 해당 기능이 구현되지 않았다면 nil을 반환한다

프로토콜 타입으로 저장하기

let basic: MusicPlayer = BasicPlayer()       // 선택적 요구사항을 구현하지 않은 객체
let advanced: MusicPlayer = AdvancedPlayer() // 선택적 요구사항을 구현한 객체

basic.play()                     // 출력: 음악 재생 중... 볼륨: 5
print(basic.volume ?? 0)         // 출력: 5 (옵셔널 타입을 안전하게 해제하여 출력)

advanced.play()                  // 출력: 고급 플레이어에서 음악 재생 중... 볼륨: 10
advanced.shuffle?()              // 출력: 곡을 무작위로 섞기 (선택적 요구사항 호출)
  • basicshuffle() 메서드를 구현하지 않았으므로 호출할 수 없다
  • advancedshuffle() 메서드를 구현했으므로 안전하게 사용할 수 있다
  • 선택적 요구사항을 호출할 때는 옵셔널 체이닝 (?()) 을 사용한다

프로토콜 타입으로 저장할 때의 주의점

print(basic.volume)            // 에러 발생 - Optional 타입이므로 옵셔널 체이닝이 필요
print(basic.volume ?? 0)        // 올바른 사용법 (옵셔널을 안전하게 해제)
  • volume 속성은 선택적 요구사항으로 정의되었기 때문에, basic 객체로 접근하면 옵셔널 타입(Int?)으로 인식된다
  • 안전하게 접근하려면 옵셔널 바인딩 또는 기본값을 사용해야 한다

구조체와 열거형은 선택적 요구사항을 구현할 수 없다

  • 선택적 요구사항은 @objc를 사용하기 때문에 클래스 전용으로 동작한다
  • 구조체와 열거형에서는 프로토콜을 채택할 수 없다
  • Swift의 구조체와 열거형은 Objective-C와의 호환성을 제공하지 않기 때문이다

요약

  • 선택적 요구사항은 @objc@objc optional로 정의할 수 있다
  • 선택적 요구사항은 Objective-C의 특징을 활용한 기능으로, Swift의 구조체와 열거형에서는 사용 불가하다
  • 선택적 요구사항을 호출할 때는 옵셔널 체이닝을 사용해야 한다 (?())
  • 선택적 요구사항을 포함하는 프로토콜은 클래스 전용 프로토콜로 정의된다
profile
iOS 개발자 지망생

0개의 댓글