Search

[정리] SwiftUI - 애플 도큐먼트 튜토리얼 정리(2편)

contents

 Swift

lazy

우리가 아는 lazy var말고도 LazySequence가 존재한다.
Swift 표준 라이브러리에서 SequenceType 및 Collection Type 프로토콜에는 lazy라는 연산 프로퍼티가 있으며, 이 클래스는 특수 LazySequence 또는 LazyCollection를 반환합니다.
let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: path] })
Swift
복사
map, flatMap, filter 같은 고차함수에서 사용 가능하다.
lazy를 사용하지 않은 예시
lazy 사용 예시

Chaining lazy sequences

func increment(x: Int) -> Int { print("Computing next value of \(x)") return x+1 } func double(x: Int) -> Int { print("Computing double value of \(x)…") return 2*x } let doubleArray = array.lazy.map(increment).map(double) print(doubleArray[3])
Swift
복사
진행 순서
결과
print(doubleArray[3])
doubleArray 연산 시작
doubleArray[3]
3
increment(x: 3)
4
double(x: 4)
8

Protocol

Hashable

Hash Value : 데이터를 간단한 숫자로 변환한 것 - 원본 데이터(객체)를 해쉬 함수을 사용하여 64bit의 Int값으로 변환한 값 - 2개의 데이터를 비교할 때, 데이터가 동일하면 각 데이터의 해쉬값도 동일하다.(단, 해쉬값은 코드를 컴파일 및 실행할 때마다 변경된다)
let hi: String = "안녕하세요" let hello: String = "안녕하세요" let apple: String = "애플" print(hi.hashValue) // 2897817589225975386 - 해쉬값 print(hello.hashValue) // 2897817589225975386 print(apple.hashValue) // 1147360803777020165
Swift
복사
  단, 2개의 서로 다른 데이터가 동일한 해쉬값을 가질 수도 있다. 해쉬값은 일정 크기의 Int값이므로 유한하고, 데이터 양은 무한하기 때문에 해쉬값이 충분하지 않기 때문이다.   해쉬 충돌 발생   다른 데이터 구조(연결 리스트, 선형조사법 등)를 사용하여 해결 가능
Q. Hashable?
A. Hashable한 타입의 데이터는 해쉬값(hash value)을 구할 수 있다.
A type must be hashable in order to be stored in a set.
Set에 어떤 값을 저장하고 싶다면, “해당 값의 타입은 Hashable”해야 한다는 뜻. 즉, Hashable Protocol를 Conform해야 한다.
Hashable를 준수한 구조체는 인스턴스끼리 == 연산자로 비교 가능하다.
Hashable Protocol이 Equatable Protocol를 준수하고 있기 때문에
public protocol Hashable : Equatable { var hashValue: Int { get } func hash(into hasher: inout Hasher) }
Swift
복사
hashValue 프로퍼티를 통해 해쉬값을 확인할 수 있다.
구조체의 경우, 저장프로퍼티는 모두 Hashable을 준수해야 한다.
Q. 어디서 Hashable한 타입을 사용하나요?
A. Swift에서 Set 타입의 값, Dictionary 타입의 Key는 Hashable해야 한다. 또한 Swift의 기본 타입인 String, Int 등은 자동으로 Hashable하다. Enum은 associated value를 가지지 않으면 자동으로 Hashable하다.
Q. 왜 사용하나요?
A. 값의 검색 속도가 빠르기 때문. 해쉬 테이블에서는 해쉬값을 index로 사용하여 원하는 값의 위치를 한 번에 알 수 있다. → 시간복잡도 O(1)
  Swift의 Set과 Dictionary는 Array와 다르게 “순서가 없기 때문에” 관련이 있는 듯 하다.

Identifiable(iOS 13+, Swift5.1)

단순히 id 프로퍼티를 가지고 있는 형태 - 어떤 struct, class를 정의할 때 ID값이 필요한 경우 해당 Protocol를 Conform - 인스턴스의 유일성을 보장하기 위해 ID값을 설정할 것을 강제하는 프로토콜
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) public protocol Identifiable { /// A type representing the stable identity of the entity associated with /// an instance. associatedtype ID : Hashable /// The stable identity of the entity associated with this instance. var id: Self.ID { get } }
Swift
복사
Student들을 구별할 때 ID값 필요
struct Student: Identifiable { let id: String let name: String }
Swift
복사

backtick variables

상수와 변수의 명명규칙에 의해서 변수에는 쓸 수 없는 문자들이 일부 존재한다. Swift 내부에서 사용되고 있는 키워드 또한 사용할 수 없다. 하지만 굳이 이 키워드를 써야한다고 할 때 변수나 상수명 앞뒤로 backticks(`)를 붙여주어 사용할 수 있다.
예시
enum Foo { case `var` case `let` case `class` case `func` } let items = [Foo.class, Foo.let, .var]
Swift
복사
Swift 4.2 이전에는 self에 대한 Strong Reference를 유지하고 이름을 유지하기 위해서는 backtick를 사용해야 했는데 Swift 4.2부터는 backtick없이 사용 가능합니다.
self.provider.fetchData { [weak self] (fetchedData) in guard let `self` = self else { return } let processedData = self.processData(fetchedData) self.updateUI(with: processedData) }
Swift
복사
self.provider.fetchData { [weak self] (fetchedData) in guard let self = self else { return } let processedData = self.processData(fetchedData) self.updateUI(with: processedData) }
Swift
복사

static func / class func

Swift에는 instance class static 함수가 있습니다.
// 1. instance func instanceFunc() { } // 2. class class func classFunc() { } // 3. static static func staticFunc() { }
Swift
복사
공통점
static funcclass func타입 메소드라고 불립니다. class 객체보다는 class 자체에 연관이 되어 있어서 () 생성자를 통해서 인스턴스를 생성하지 않더라도 바로 접근 가능합니다.
Object.classFunc() Object.staticFunc()
Swift
복사
차이점
Override의 여부
class 함수는 override가 가능합니다.
static 함수는 override가 불가능합니다.
상속이 불가능한 struct, enum에서 class func를 정의하면 에러가 발생합니다.
final
final 사용 이유
final 키워드 적용이 성능에 미치는 영향
오버라이딩한 메서드는 실행 시점에 어떤 메서드를 실행할지 결정하는 반면, final 키워드가 적용된 메서드는 컴파일 시점에 어떤 메서드를 실행할지 결정할 수 있으므로 성능 상 이점을 가진다고 할 수 있습니다.
class 앞에 final 키워드를 붙여주면 상속을 막아주기 때문에 static과 같은 의미가 됩니다.
class TestClass: Test { override final class func classFunc() override static func staticFunc() }
Swift
복사
Q. 언제 static를 사용하는가?
Swift에서 static 키워드를 사용하는 경우는 해당 메소드나 프로퍼티가 instance보다는 type자체와 연관될 때입니다.
static property
자주 안 변하고 전역 변수마냥 공통으로 관리하는 공용 자원 느낌 → 색상, 폰트 등
static var gray000: UIColor { return UIColor(hex: "#f3f3f3") }
Swift
복사
자주 재사용되고 생성 비용이 많이드는 object를 미리 만들어 놓고 계속 쓰면 효율을 높일 수 있을 때 → dateformatter 등
static var className: String { return String(describing: self) }
Swift
복사
static method
간단한 factory 패턴 구현
static func randomName() -> String { if let random = symbolNames.randomElement() { return random } else { return "" } }
Swift
복사

 SwiftUI

Life Cycle

Data Flow Through SwiftUI

Session Capture
Content

Data Essentials in SwiftUI

Session Capture

State and Data Flow

Document Content

onAppear / onDisappear

SwiftUI에는 View의 상태를 나타내는 함수가 단 두가지 밖에 없다.
대신 상태를 나타내는 다양한 Property Wrapper가 존재해 Data flow에 대한 여러 상태에 대응할 수 있다.
.onAppear { print("View appeared") } .onDisappear { print("View disappeared") }
Swift
복사