iOS 공부(Swift 기본 문법) - 4

박준수·2022년 3월 31일
0

Swift 기본 문법

목록 보기
4/4
post-thumbnail

try-catch

enum PhoneError: Error {
	case unknown
    case batteryLow(batteryLevel: Int)
}

Error 를 표현하기 위해서는 Error 프로토콜을 채택해야 한다.

에러를 처리하는 방법

함수에서 발생한 에러를 해당 함수를 호출한 코드에 전파

func checkPhoneBatteryStatus(batteryLevel: Int) throws -> String {
	guard batteryLevel != -1 else { throw PhoneError.unknown }
    guard batteryLevel > 20 else { throw PhoneError.batteryLow(batteryLevel: batteryLevel) }
    return "배터리 상태가 정상입니다."
}

do-catch 구문

do {
	try checkPhoneBatteryStatus(batteryLevel: -1)
} catch PhoneError.unknown {
	print("알 수 없는 에러입니다.")
} catch PhoneError.batteryLow(let batteryLevel) {
	print("배터리 전원 부족, 남은 배터리 : \(batteryLevel)%")
} catch {
	print("그 외 오류 발생 : \(error)")
}

Optional로 처리

let status1 = try? checkPhoneBatteryStatus(batteryLevel: -1)
print(status1) // nil

let status2 = try? checkPhoneBatteryStatus(batteryLevel: 30)
print(status2) // Optional("배터리 상태가 정상입니다.")

발생한 에러를 try? 로 처리하면 nil 을 반환
에러가 발생하지 않을 것이라고 확신한다면 try! 를 사용하여 강제적으로 Optional 을 해제해줄 수 있다.(권장 X)

클로저

일급 객체

전달 인자로 보낼 수 있고, 변수/상수 등으로 저장하거나 전달할 수 있으며, 함수의 반환 값이 될 수도 있다.

{ (매개 변수) -> 리턴 타입 in
	실행 구문
}

변수나 상수에 대입

let hello1 = { () -> () in
	print("hello")
}

hello1() // hello

let hello2 = { (name: String) -> String in
	return "Hello, \(name)"
}

hello2("Park") // Hello, Park

일반 함수를 호출하듯이 hello2(name: "Park") 처럼 사용하면 에러가 발생한다. 전달인자 레이블을 적지 않아야 한다.

함수에 파라미터로 전달

func doSomething1(closure: () -> ()) {
	closure()
}

doSomething1(closure: { () -> () in
	print("hello")
}) // hello

함수의 반환 타입으로 사용

func doSomething2() -> () -> () {
	return { () -> () in
    	print("hello")
    }
}

doSomething2()() // 매개변수를 넣을 수 있는 곳이 2곳이라 이렇게 쓰나 보다.

후행 클로저

후행 클로저를 사용하면 클로저를 간단히 표현할 수 있다.
매개변수로 클로저가 여러 개 전달될 경우에는 마지막 매개변수에 해당하는 클로저만 후행 클로저로 사용할 수 있다.

doSomething1() {
	print("hello")
}

하나의 클로저만 매개변수로 전달하는 경우에는 매개변수 부분의 소괄호도 생략할 수 있다.

doSomething1 {
	print("hello")
}

다중 후행 클로저

매개변수로 클로저가 여러 개 전달될 경우

func doSomething3(success: () -> (), fail: () -> ()) {
}

doSomething3 {
	실행 코드
} fail: {
	실행 코드
}

첫번째 클로저는 전달인자 레이블 생략

클로저 표현을 간소화하는 방법

func doSomething4(closure: (Int, Int, Int) -> (Int)) {
	closure(1, 2, 3)
}

doSomething4(closure: { (a, b, c) in
	return a + b + c
}) // 일반적인 호출

doSomething4(closure: {
	return $0 + $1 + $2
}) // 파라미터 형식 생략

doSomething4(closure: {
	$0 + $1 + $2
}) // 리턴 형식 생략(블록에 리턴 구문만 남는 경우에만 가능)

doSomething4() {
	$0 + $1 + $2
} // 후행 클로저 사용

doSomething4 {
	$0 + $1 + $2
} // 매개변수로 하나의 클로저만 전달되기 때문에 소괄호까지 생략 가능

고차함수

다른 함수를 전달 인자로 받거나 함수 실행의 결과를 함수로 반환하는 함수
(map, filter, reduce)

map

let numbers = [0, 1, 2, 3]
let mapArray = numbers.map { (number) -> Int in
	return number * 2
}

print("map \(mapArray)") // map [0, 2, 4, 6]

filter

let intArray = [10, 5, 20, 13, 4]
let filterArray = intArray.filter { $0 > 5 } // 위에서 다룬 클로저 단순화 사용

print("filter \(filterArray)") // filter [10, 20, 13]

reduce

let someArray = [1, 2, 3, 4, 5]
let reduceResult = someArray.reduce(0) {
	(result: Int, element: Int) -> Int in
    	print("\(result) + \(element)")
        return result + element
} // 0은 초기값, result에는 누적값, element는 배열의 원소

print("reduce \(reduceResult)")
/*
	0 + 1
    1 + 2
    3 + 3
    6 + 4
    10 + 5
    reduce 15
*/

출처

패스트캠퍼스, 초격차 패키지 : 30개 프로젝트로 배우는 iOS 앱 개발 with Swift

profile
안녕하세요!!

0개의 댓글

관련 채용 정보