안녕하세요. 에밀리입니다.
써도 써도 헷갈리는 block에 대해 알아보겠습니다.
Block이 무엇인지, 우리가 주로 쓰는 completion은 어떤 형태로 돼있는지 설명합니다.
블록이란?
콜백 함수 Objective-C 버전.
Delegation을 이용해도 되지만 프로토콜 생성, 메소드 구현 등등 작업 단위가 많은데, Block은 그에 비해 구현이 간단할 때 씁니다.
기본적인 블록 선언 방법
^{
NSLog(@"This is a block");
}
위에서 ^표시가 블록임을 선언합니다. {} 안에 작동할 코드를 넣어줍니다.
블록 형식
기본적인 objective-c 함수 선언은 다음과 같습니다.
void methodName:(void)name;
블록 선언은 함수 선언 방식과 비슷합니다.
반환형 (^블록명)(파라미터 타입);
ex)
void (^blockName)(void);
반환형을 바꿀 수도 있고, 파라미터를 여러개 넣을 수도 있습니다.
double (^blockName)(double, double);
블록을 함수 Argument로 전달한다
많이 쓰는 completionHandler가 이런 형식입니다.
보통 함수 선언 형식은 다음과 같습니다.
- (void) exampleMethodName:(NSString *)string;
여기서 (NSString *)string 자리에 block이 들어갈 수도 있습니다.
- (void)exampleMethodName:(블록 선언이 들어갈 자리)블록 이름;
그럼 예시로 위에서 선언했던 블록 형식인
void (^blockName)(void);
이 친구를 그대로 (블록 선언이 들어갈 자리)에 넣어보겠습니다.
- (void)exampleMethodName:(void (^blockName)(void))methodBlockName;
여기서 blockName은 생략 가능합니다.
- (void)exampleMethodName:(void (^)(void))methodBlockName;
원래 NSString 같은 타입이 들어가던 자리에 블록 타입이 들어갔습니다.
methodBlockName은 exampleMethodName 함수 안에서 쓸 블록 이름입니다.
exampleMethodName 안에서 methodBlockName()으로 호출도 가능합니다.
- (void)exampleMethodName:(void (^)(void))methodBlockName { ... methodBlockName();}
block에 파라미터가 여러개 들어갈 수 있으니 argument로 들어갈 때도 여러개 들어갈 수 있습니다.
- (void)doSomethingWithBlock:(void (^)(double, double))block { ... block(21.0, 2.0);}
함수 선언할 때 블록 선언은 맨 끝에 해야한다.
예를들면 이렇게
- (void)beginTaskWithName:(NSString *)name completion:(void(^)(void))callback;
completion이 맨 끝에 선언된 게 보이죠?
이유는 가독성이 좋기 때문입니다.
결과적으로 beginTaskWithName 함수를 사용할 때, completion 블럭은 이렇게 동작합니다.
[self beginTaskWithName:@"MyTask" completion:^{ NSLog(@"The task is complete");}];
우리가 많이 보는 completion 구문이죠.
이상 block에 대해 알아보았습니다.