이 글은 애플 측 개발자 문서인 Working with Blocks를 바탕으로 작성한 것입니다. Swift의 ‘클로저(closure)’에 대응하는 Objective-C의 ‘블록(block)’에 대한 내용입니다.
Objectiv-C 블록(block)으로 작업하기
Objective-C 클래스는 데이터 및 이에 관계된 행동으로 구성된 객체를 정의합니다. 때때로 Objective-C에서는 일련의 메소드들보다는 하나의 작업 또는 단위 행동을 표현하는 다른 방법을 찾는 것이 더 나은 경우도 있습니다. 블록(block)은 C, Objective-C 및 C++에서 마치 변수처럼 다른 곳으로 어떤 메소드나 함수 조각을 전달하기 위한 언어 수준에서 정의된 기능입니다. 블록은 Objective-C에서 객체인데 이는 NSArray
나 NSDictionary
같은 콜렉션으로 추가될 수 있음을 뜻합니다. 블록은 또한 자신을 감싸고 있는 스코프에서 값을 캡쳐할 수 있는 능력을 가지고 있는데 이는 타 프로그래밍 언어에서 ‘클로저(closure)’나 ‘람다(lambda)’와 비슷합니다. 이 장에서는 블록을 선언하고 참조하는 구문에 대해 설명하고 콜렉션 열거와 같은 통상적인 작업에서 블록을 사용하는 방법에 대해 보일 것입니다.
블록 구문
블록을 정의하는 구문은 다음과 같이 ‘캐럿(caret)’ 기호(^)를 사용합니다.
// Objective-C
^{
NSLog(@"This is a block");
}
함수나 메소드 정의와 마찬가지로 중괄호는 블록의 시작과 끝을 지시합니다. 이 예에서 블록은 어떤 값도 반환하지 않도 어떤 매개변수도 받지 않습니다.
여러분이 C 함수를 참조하고 어딘가로 이를 전달하기 위해 함수 포인털르 사용하듯이, 여러분은 Objective-C에서 다음과 같이 블록을 보관할 수 있는 변수를 선언할 수 있습니다.
// Objective-C
void (^simpleBlock)(void);
여러분이 C 함수 포인터를 다루는 것에 익숙하지 않다면, 이런 구문이 다소 이상해 보일 것입니다. 다음 예는 simpleBlock
이라는 변수에 매개변수도 없고 반환 타입도 없는 블록을 참조시킬 것입니다.
// Objective-C
simpleBlock = ^{
NSLog(@"This is a block");
}
이것은 통상의 변수 대입과 차이가 없습니다. 그래서 문장의 끝은 세미콜론으로 끝납니다. 여러분은 다음과 같이 변수의 선언과 대입을 한 문장으로 적을 수 있습니다.
// Objective-C
void (^simpleBlock)(void) = ^{
NSLog(@"This is a block");
};
일단 변수를 선언하고 대입한 후에 다음과 같이 블록을 호출 및 실행할 수 있습니다.
// Objective-C
simpleBlock();
참고 블록이 대입되지 않은 변수 또는 nil
이 대입된 변수를 호출하려 할 경우 앱은 충돌합니다.
매개변수를 받고 값을 반환하는 블록
블록도 메소드 또는 함수와 마찬가지로 매개변수를 받고 값을 반환할 수 있습니다. 다음 예는 두 개의 값을 받아서 그 값을 곱한 결과를 반환하는 블록을 참조하는 변수입니다.
// Objective-C
double (^multiplyTwoValues)(double, double);
여기에 참조될 수 있는 블록은 다음과 같이 생겼습니다.
// Objective-C
^(double firstValue, double secondValue) {
return firstValue * secondValue;
}
보통의 함수와 마찬가지로 firstValue
와 secondValue
는 블록이 호출될 때 주어진 값을 참조합니다. 이 예제에서 블록의 반환 형식은 블록 내의 return
문장이 반환하는 형식에서 유래된 것입니다. 물론 여러분의 선호에 따라 캐럿과 매개변수 목록 사이에 블록의 반환 형식을 직접 명시할 수도 있습니다.
// Objective-C
^ double (double firstValue, double secondValue) {
return firstValue * secondValue;
}
블록을 일단 선언 및 정의하고 변수에 참조시키면 여러분은 그 이후부터는 함수처럼 호출할 수 있습니다.
// Objective-C
double (^multiplyTwoValues)(double, double)
= ^(double firstValye, double secondValue) {
return firstValue * secondValue;
}