Swift 127

[Swift] difference(from:)와 applying(_:)

difference(from:) difference(from:)은 두 개의 Collection 차이를 쉽게 구할 수 있는 메서드입니다. A와 B를 비교했을 때 무엇이 추가로 있고, 무엇이 없는지 알 수 있습니다. (A collection of insertions and removals that describe the difference between two ordered collection states.) 사용법도 간단합니다. let arr1 = [1, 2, 3, 4] let arr2 = [1, 3, 4, 5] let diff = arr2.difference(from: arr1) diff를 출력해 보면 arr1이 arr2가 되기 위해 무엇을 추가하고, 무엇을 빼야 하는지 알 수 있습니다. "Collect..

[Swift] 프로토콜 메서드의 매개변수 기본 값 설정 (Defining default parameters for protocol methods)

서론 프로토콜 타입을 사용할 때 불편한 점이 하나 있습니다. 메서드 파라미터에 기본 값을 사용할 수 없다는 점입니다. 예를 들어, UseCase의 execute 파라미터로 page를 전달해야 한다고 합시다. protocol UseCaseProtocol { func execute(page: Int) } struct UseCase: UseCaseProtocol { func execute(page: Int) { // Logic } } let useCase: UseCaseProtocol = UseCase() useCase.execute(page: 1) 그러면 위 코드처럼 항상 page를 전달해줘야 해요. page에 기본 값을 설정하고 싶어도 프로토콜 메서드에는 Default argument를 설정할 수 없다는 ..

[Swift] NSCoding과 Codable 차이점 (상속 관계 유지하기)

NSCoding과 Codable Codable이 나오면서 NSCoding은 옛날의 그것으로 생각되었습니다. 그런데 NSCoding만이 할 수 있는 일이 있었습니다. 바로 상속 관계를 유지해서 저장하는 것입니다. Shape 부모 클래스를 상속하는 두 개의 자식 클래스가 있습니다. class Plane { var shapes: [Shape] init(shapes: [Shape]) { self.shapes = shapes } func display() { for shape in shapes { print("\(type(of: shape)): \(shape.description)") } } } let shapes: [Shape] = [ Rect(point: .init(x: 10, y: 10), size: .in..

[Swift] 구조체와 클래스의 Property Observer 동작 차이 (짧은글)

Property Observer Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value. Property Observer는 프로퍼티의 "값"이 변하면 호출됩니다. 여기서 "값"의 의미때문에 구조체와 클래스의 프로퍼티 옵저버 동작 차이가 발생합니다. struct StructA { var value: Int = 0 } class ClassA { var value: Int = 0 } var struc..

[Swift] OptionSet 알아보기

OptionSet OptionSet은 비트 마스크를 이용해 여러 옵션을 다룰 때 채택하는 프로토콜입니다. 프로토콜이지만 이름에 Set이 붙은 거처럼 분류도 Collections로 되어 있고, intersection, union 등 집합 메서드도 사용할 수 있습니다. (이건 아래에서 더 자세히 알아볼게요.) OptionSet이 낯설 수 있는데요. 생각보다 많은 곳에서 사용됩니다. 대표적으로 UIView.AnimationOptions, UIView.AutoresizingMask가 있습니다. OptionSet 사용법 struct ShippingOptions: OptionSet { let rawValue: Int static let nextDay = ShippingOptions(rawValue: 1

[Swift] Equatable의 Synthesized Conformance 분석

서론 구조체와 클래스의 프로토콜 자동 준수 메커니즘 (w. ChatGPT)에서 Synthesized Conformance를 가볍게 다뤘습니다. 이번 포스팅에서는 SIL, CPP 코드를 분석해 Equatable의 Synthesized Conformance가 진행되는 과정을 알아보겠습니다. Equatable Equatable은 == static 메서드를 준수해야 하는 프로토콜로 == 연산자의 좌변과 우변을 비교해서 같은지 확인해 주는 역할입니다. 그리고 Synthesized Conformance를 지원하는 프로토콜 중 하나죠. Equatable은 아래 상황에서 Synthesized Conformance를 지원합니다. 구조체가 Equatable을 준수하는 저장 프로퍼티만 가지고 있는 경우 열거형의 모든 케이스..

[Swift] 구조체와 클래스의 프로토콜 자동 준수 메커니즘 (w. ChatGPT)

서론 최근 Equatable, Hashable, Comparable을 복습하면서 궁금한 점이 있었습니다. 왜 구조체는 채택만 해도 자동으로 준수가 되는데 클래스는 직접 요구 메서드를 구현해야 하는 걸까?입니다. Value 타입과 Reference 타입의 차이와 연관이 있다는 건 추측할 수 있었지만, 명확한 이유를 찾긴 어려웠습니다. 그래서 이번에는 ChatGPT와 함께 문제를 해결해 보았습니다. 스텝 바이 스텝으로 대답이 정확해지는 과정이 재밌어서 이렇게 포스팅으로 남겨봅니다. 1. 일단 질문하기 일단 큰 고민 없이 물어봤습니다. 그럴듯한 대답이 나왔습니다만, "값 타입이 프로토콜을 채택만 해도 되는 이유"에 대한 답은 아니었습니다. 2. 클래스와 비교하여 질문 다음은 클래스와 비교해서 질문했습니다. 이..

[Swift] Optional.swift 살펴보기

Optional.swift를 살펴보게 된 계기 옵셔널은 Swift의 장점 중 하나입니다. 백준 문제를 풀다가 문득 nil 병합 연산자(??)에 대해 궁금해졌습니다. 일반적인 연산자는 즉시 연산이 완료되는데, ?? 연산자는 앞의 수행 결과가 nil인 경우 실행이 되는 부분이 흥미로웠어요. 어떻게 구현되었길래 지연 실행이 되는거지? 라는 생각이 들었습니다. 많은 블로그에서 이미 다룬 주제지만, 실제 구현 코드가 궁금해서 Optional.swift를 살펴봤는데요. 보기 전에는 너무 어려워서 못 읽을 줄 알았지만 막상 보니 읽을만 한거에요..? 그래서 한 번 쫙 읽고 포스팅으로 정리까지 하게 되었습니다 ㅋㅋ 전부 다루는건 아니기 때문에 Optional.swift와 함께 보시면 좋습니다. 기본 구조 @frozen..

[Swift] Generic, Protocol을 이용한 Extension Wrapping

Extension Wrapping Extension Wrapping은 유명 라이브러리에서 자주 보이는 구조입니다. (참고로 Extension Wrapping은 정식 명칭이 아니라 제가 임의로 정한 이름입니다.) 대표적으로 Kingfisher, RxSwift가 있습니다. imageView.kf.setImage(with: url) Kingfisher 메서드를 사용할 때 UIImageView가 아니라 kf를 이용해 메서드를 호출하죠? 바로 그게 Extension Wrapping입니다. Extension으로 구현한 Kingfisher 메서드를 UIView에서 직접 호출하지 않고, KingfisherWrapper로 호출하는 것입니다. Extension Wrapping 장점 Extension Wrapping은 안정..

[Swift] Failable Initializer (실패 가능한 초기화)

Failable Initializer Failable 초기화는 실패가 가능한 초기화입니다. 클래스, 구조체, 열거형에서 실패 가능한 초기화를 정의할 수 있습니다. Failable 초기화 예시 실패가 가능한 초기화는 특정 조건에서만 객체가 생성되어야 할 때 유용합니다. class Time { var hour: Int var minute: Int } 예를 들어, Time 클래스는 hour와 minute 변수가 있습니다. hour의 범위는 1~12여야 하고, minute은 0~59여야 합니다. 이외의 숫자가 들어오면 객체가 생성되지 않도록 하고 싶을 때 Failable 초기화를 사용할 수 있습니다. class Time { var hour: Int var minute: Int init?(hour: Int, mi..

반응형