https://developer.apple.com/videos/play/wwdc2022/110352
2022년 6월 9일 기준 XCode 14.0 베타 버전이 사용 가능합니다. WWDC22에서 소개된 내용을 직접 사용해보고자 XCode 14.0 베타 버전을 설치하고, 아래 메소드를 소개된 내용으로 바꿔봤습니다.
func startRecord<T>(deviceInput: AVCaptureDeviceInput, recorder: T, deviceOrientation: AVCaptureVideoOrientation) where T: AVCaptureFileOutputRecordingDelegate { ... }
아래와 같이 바꾸고 빌드하면 정상적으로 빌드됩니다.
func startRecord(deviceInput: AVCaptureDeviceInput, recorder: some AVCaptureFileOutputRecordingDelegate, deviceOrientation: AVCaptureVideoOrientation) { ... }
아래와 같은 예시도 있습니다.
func prepareToUseDevice<T>(at index: Int, presenter: T) where T: UIViewController & AVCaptureVideoDataOutputSampleBufferDelegate { ... }
func prepareToUseDevice(at index: Int, presenter: some UIViewController & AVCaptureVideoDataOutputSampleBufferDelegate) { ... }
신기한 부분은 프로토콜에서 아래와 같이 정의했음에도 메소드 구현을 some
을 포함한 형태로 구현했을 때 빌드가 된다는 점입니다. 반대의 경우도 빌드가 됩니다.
protocol StudioConfigurable {
func prepareToUseDevice<T>(at index: Int, presenter: T) where T: UIViewController & AVCaptureVideoDataOutputSampleBufferDelegate
}
전체 코드는 아래와 같습니다.
protocol AnimalFeed {
associatedtype CropType: Crop where CropType.Feed == Self
static func grow() -> CropType
}
protocol Crop {
associatedtype Feed: AnimalFeed where Feed.CropType == Self
func harvest() -> Feed
}
protocol Animal {
associatedtype Feed: AnimalFeed
func eat(_ food: Feed)
}
struct Farm {
func feed(_ animal: some Animal) {
let crop = type(of: animal).Feed.grow()
let produce = crop.harvest()
animal.eat(produce)
}
func feedAll(_ animals: [any Animal]) {
for animal in animals {
feed(animal)
}
}
}
struct Cow: Animal {
func eat(_ food: Hay) {}
}
struct Hay: AnimalFeed {
static func grow() -> Alfalfa {
Alfalfa()
}
}
struct Alfalfa: Crop {
func harvest() -> Hay {
Hay()
}
}
아래 구조체가 iOS 16부터 바꿀 수 있는 표현을 보여주고 있습니다.
struct Farm {
func feed(_ animal: some Animal) {
let crop = type(of: animal).Feed.grow()
let produce = crop.harvest()
animal.eat(produce)
}
func feedAll(_ animals: [any Animal]) {
for animal in animals {
feed(animal)
}
}
}
위 구조체 중 첫 번째 메소드는 아래 메소드와 같습니다.
struct Farm {
func feed<T>(_ animal: T) where T: Animal {
let crop = type(of: animal).Feed.grow()
let produce = crop.harvest()
animal.eat(produce)
}
}
다음과 같이 선언할 수도 있습니다.
protocol Animal {
}
class Horse: Animal {
}
class Chicken: Animal {
}
var animal: some Animal = Chicken()