THIS IS ELLIE

스탠포드 SwiftUI강의 복습하기 Lecture4 본문

개발/SwiftUI

스탠포드 SwiftUI강의 복습하기 Lecture4

Ellie Kim 2021. 2. 3. 03:44

Array+Only

배열의 Element가 오직 한 개인지 확인하는 연산 프로퍼티 정의.
배열 Element개수가 1개면 first를 리턴하고 아니면 nil을 리턴.

 

Array+Identifiable

Array의 Element가 Identifiable을 준수할 때
firstIndex(matching: Element) -> Int? 함수를 사용해 원하는 인덱스를 가져올 수 있다.

 

Grid

Item, ItemView는 제네릭이 때문에 타입은 몰라도 되고 where을 통해 Identifiable, View라는 제약을 준다.
init부분에 viewForItem은 초기화 할 때 사용하지 않고 나중에 사용되기 때문에 @escaping을 붙혀줌.
이는 레퍼런스 타입이며 힙에 존재한다.

 

모델

mutating func choose(card: Card)를 통해 비교.
if 조건문 chosenIndex에는 현재 내가 선택한 인덱스, 내가 선택한 인덱스의 카드가 isFaceUp이 아니고, 내가 선택한 카드가 isMatched가 아니 여야 한다.
- indexOfTheOneAndOnlyFaceUpCard에 값이 존재한다면 내가 현재 뽑은 인덱스의 content와 indexOfTheOneAndOnlyFaceUpCard의 content가 같은지 확인해준다. 같다면 두 카드에 대해서 isMatched값을 true로 변경해준다. 그리고 선택한 카드를 뒤집어준다.
- indexOfTheOneAndOnlyFaceUpCard에 값이 존재하지 않는다면 indexOfTheOneAndOnlyFaceUpCard에 내가 선택한 인덱스 값을 넣어준다.

여기서 카드 content가 가능한 이유는 Equatable프로토콜을 채택해줬기 때문이다.
CardContent는 제네릭이니까 아무 타입이 올 수 있다. 
지금과 같이 문자열이면 크게 상관이 없지만 이미지이면 같은지 비교가 안된다.

public protocol Equatable {
    /// Returns a Boolean value indicating whether two values are equal.
    ///
    /// Equality is the inverse of inequality. For any values `a` and `b`,
    /// `a == b` implies that `a != b` is `false`.
    ///
    /// - Parameters:
    ///   - lhs: A value to compare.
    ///   - rhs: Another value to compare.
    static func == (lhs: Self, rhs: Self) -> Bool
}

그러므로 Equatable프로토콜을 채택하고 필수 함수를 구현해준다.


뷰모델

이전과 크게 달라진 점이 없다.
2021/01/29 - [개발/SwiftUI] - 스탠포드 SwiftUI강의 복습하기 Lecture3

 

if !card.isMatched를 조건문을 추가해 카드가 매칭 되지 않으면 다시 뒤집어준다.

 

실행 결과

 


옵셔널

옵셔널은 아래와 같이 구현되어 있다.

enum Optional<T> { // a generic type
	case none
	case some(T) // the some case hase associated value of type T
}

var hello: String? 코드는 nil이 암묵적으로 초기화 된 것이기 때문에 어떠한 에러를 내지 않는다.
즉 var hello: String? = nil이라는 것.

옵셔널 언래핑하는 3가지 상황을 나타낸다. 

1) !

let hello: String? = …

print(hello!)

switch hello {
	case .none: //raise an exception (crash)
	case .some(let data): print(data)
} 

2) if let 

let hello: String? = …

if let safehello = hello {
	print(safehello)
} else {
	// do something else
}

switch hello {
	case .none: { // do something else }
	case .some(let data): print(data)
}

3) ??

let x: String? = …
let y = x ?? “foo”

switch x {
	case .none: y = “foo”
	case .some(let data): y = data
}

 

반응형