본문 바로가기

iOS-Study

iOS Study : 7주차 - Swift 공식 문서 정리

Enumerations and Structures(열거형과 구조체)

  • 열거형을 만들기 위해서는 enum을 사용한다.
  • rawValue를 사용하여 정수값을 가지게 할 수도 있다.
  • rawValue를 통해 초기화도 가능하다. 이 때 rawValue가 case에 해달하지 않을 수 있기 때문에 rawValue를 통해
    초기화 한 인스턴스는 옵셔널 타입이다.
  • switch문에 모든 열거형 케이스를 포함한면 default를 작성할 필요가 없다.
enum Rank: Int {
    case ace = 1
    case two, three, four, five, six, seven, eight, nine, ten
    case jack, queen, king

    func simpleDescription() -> String {
        switch self {
        case .ace:
            return "ace"
        case .jack:
            return "jack"
        case .queen:
            return "queen"
        case .king:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
}
let ace = Rank.ace
let aceRawValue = ace.rawValue
enum Suit {
    case spades, hearts, diamonds, clubs

    func simpleDescription() -> String {
        switch self {
        case .spades:
            return "spades"
        case .hearts:
            return "hearts"
        case .diamonds:
            return "diamonds"
        case .clubs:
            return "clubs"
        }
    }
}
let hearts = Suit.hearts
let heartsDescription = hearts.simpleDescription()
struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

 

Concurrency(동시성)

  • 비동기적으로 실행되는 함수를 표시하기 위해 async를 사용한다.
func fetchUserID(from server: String) async -> Int {
    if server == "primary" {
        return 97
    }
    return 501
}
  • await을 함수 앞에 붙여 비동기 함수에 대한 호출을 표시한다.
func fetchUsername(from server: String) async -> String {
    let userID = await fetchUserID(from: server)
    if userID == 501 {
        return "John Appleseed"
    }
    return "Guest"
}

 

Protocols and Extensions(프로토콜과 익스텐션)

  • 프로토콜은 특정 역할을 수행하기 위한 메서드, 프로퍼티, 이니셜라이저 등의 요구사항을 정의한다.
  • protocol을 사용하여 프로토콜을 선언하는데 사용한다.
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}
  • 클래스, 열거형, 구조체 모두 프로토콜을 채택할 수 있다.
class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += "  Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
  • 익스텐션은 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있는 기능이다.
  • 타입에 새로운 기능을 추가할 수는 있지만, 재정의할 수는 없다.
extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription)
// Prints "The number 7"

 

Error Handling(오류 처리)

  • Error 프로토콜과 열거형을 통해서 오류를 표현한다.
enum PrinterError: Error {
    case outOfPaper
    case noToner
    case onFire
}
  • throw를 사용하여 오류를 내포하는 함수임을 표시한다.
func send(job: Int, toPrinter printerName: String) throws -> String {
    if printerName == "Never Has Toner" {
        throw PrinterError.noToner
    }
    return "Job sent"
}
  • 오류발생의 여지가 있는 throws 함수는 do-catch 구문을 활용하여 오류발생에 대비한다.
do {
    let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")
    print(printerResponse)
} catch PrinterError.onFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}
// Prints "Job sent"

 

 

Generic(제네릭)

  • 제네릭 함수나 타입을 만드려면 꺽쇠 괄호 안에 이름을 써준다.
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
    var result: [Item] = []
    for _ in 0..<numberOfTimes {
        result.append(item)
    }
    return result
}
makeArray(repeating: "knock", numberOfTimes: 4)
  • 제네릭은 함수나 메서드, 클래스, 열거형, 구조체로도 만들 수 있다.
// Reimplement the Swift standard library's optional type
enum OptionalValue<Wrapped> {
    case none
    case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)