minuco
article thumbnail
Published 2023. 3. 20. 18:42
[Swift] Closure 기본 개념 iOS/Swift

안녕하세요 :)

minuco입니다.

Closure 왜 사용할까??

클로저를 사용하면, 코드 중복 & 가독성 향상!

   : 비슷한 기능의 코드를 하나로 묶어서 재사용할 수 있다.

   : 함수나 메서드의 인자로 전달하는 코드를 간결하게 작성할 수 있다.(경량 문법)

   : 비동기 처리에도 용이!

 

Closure 종류

Named Closure(함수)와 UnNamed Closure(익명함수)

Named Closure는 func이라는 키워드가 붙고 함수라 부르고,

UnNamed Closure는 Closure라 부른다.

//1. function (named closure)
func plus(a: Int, b: Int) -> Int {
    return a + b
}

//2. closure (unnamed closure)
{ (a: Int, b: Int) -> Int in
    return a + b
}

//3. unnamed closure는 변수나 상수에 대입하여 사용한다.
var myClosure = { (a: Int, b: Int) -> Int in
    return a + b
}

Closure는 Head와 Body로 나뉘는데 in을 기준으로 나뉜다.

2, 3번을 보면 Code를 보면 in으로 구분 지은 걸 알 수 있죠?

 

3번의 myClosure에 클로저를 대입한 걸 볼 수 있는데, Parameter와 Return Type 이 있는 Closure는 이렇게 사용해요.

둘 다 없는 경우는 아래와 같이 표현합니다.

var myClosure = { () -> Void in
    print("myClosure")
}

// () -> Void in 를 생략해도 된다.
var myClosure = { print("myClosure") }

 

UnNamed Closure는 아규먼트 레이블의 사용할 수 없습니다.

let myClosure = { (a: Int, b: Int) -> Int in
	return a + b
}

myClosure(a: 10, b: 20) // error
myClosure(10, 20)

 

Closure + func 사용

개발을 하다 보면 function을 여러 개 사용할 경우가 허다한데, 호출 순서가 꼬일수 있다.

하지만, 클로저를 사용하면 좀 더 명시적이기 때문에 가독성이 좋아진다.

 

함수의 파라미터 타입으로 클로저를 전달하는 방법을 알아보자

 

파라미터로 클로저 전달

// func(Named Cloure) 이나 closure(unNamed Cloure)나 둘다 클로저라는 사실을 명심하고,
// closure(unName)는 Argument Label 을 사용할수 없다는걸 명시!! 

// Type이 클로저형태인 함수   
func parameter(myClosure: () -> Void){
    print("실행")
    myClosure() // 파라미터 실행구문
}

func and(){
    print("and")
}

// 실행 방법 (축약 되는 순서)
parameter(myClosure: { () -> () in print("Hello")})
parameter { () -> Void in and()}
parameter ( myClosure: { and() } )
parameter { and() }

 

파라미터 넘기기(클로저 여러개와 변수, 클로저)

// 파라미터 closure Type 2개
func myClosure1(closure1: () -> Void, closure2: () -> Void){
    print("func")
    closure1()
    closure2()
}

myClosure1 {
    print("closure1")
} closure2: {
    print("closure2")
}
/* 결과값
closure1
closure2
*/

// 파라미터 Int, closure: () -> Void
func myClosure2(a: Int, closure: () -> () ){
    print(a)
    closure()
}

myClosure2(a: 50) {
    print("closure")
}
/* 결과값
50
closure
*/

클로저를 넘기는 방법을 알아 보았는데, 함수를 넘긴다 클로저를 넘긴다. 

좀 어지럽지 않나요..? 

 

closure Type과 함수를 만들어서 파라미터로 넘기는 방법과 클로저를 직접 구현하는 방법

// closure Type과 함수를 만들어서 파라미터로 넘기기
func totalScore(completion: (Int) -> Void ) {
   print("점수를 구해서 화면에 띄워주는 작업...")
   let total = 90
   completion(total)
}

func showScore(score: Int) {
    print((score+10).description + "점")
}

totalScore(completion: showScore)

/* 결과값
점수를 구해서 화면에 띄워주는 작업...
100점
*/

// closure 직접 구현
totalScore { total in
    print(total.description + "점")
}

/* 결과값
점수를 구해서 화면에 띄워주는 작업...
90점
*/

아마 실행순서가 이해가 안될수 있다.

실행 순서를 설명하자면,

 

실행 1. 우리는 toralScore함수를 실행시키면서 showScore 함수를 파라미터 값으로 넘겨준다.

 

파라미터 값으로 넘겨줄수 있는 이유는 파라미터 변수 Type 과 showScore 함수의 Type 같기때문이다.

showScore 의 Type 는 Int 형이고 return Type 는 Void 이다.

toralScore의 파라미터 변수 Type은Int이고 return Type 는 Void이다 고로 동일하다.

 

실행 2. totalScore 의 print 문이 실행되고, completion 객체에 total 변수를 넘긴다.(즉, showScore 함수에 넘긴다.)

 

실행 3. showScore 함수가 실행된다.

 

closure 에 return 이 있는경우

func closureReturn(completion: () -> Int) {
    print("closureReturn")
    print(completion() + 10)
}

closureReturn {
    return 10
}

/* 결과값
closureReturn
20
*/

클로저는 swift에서 굉장히 중요한 부분이니 같이 적응해봐요!

빡세네;;

 

 

 

 

 

 

 

'iOS > Swift' 카테고리의 다른 글

[Swift Network] URLSession  (0) 2023.04.12
[Swift Network] URLSession - 사전지식  (0) 2023.04.12
[Swift] Closure - 축약  (0) 2023.03.23
[Swift] Closure - escaping  (0) 2023.03.23
[Swift] Closure - Capturing  (0) 2023.03.23
profile

minuco

@minuco

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!