[Objective-C] Block Syntax 초간단정리
하도 잊어먹어서 - 거기다 요즘은 Swift만 써대다보니 더욱 더 잊어먹어서 - Objective-C 블럭 문법(Block Syntax)을 자주 쓰는 것들 위주로 예제와 함께 정리해본다.
블럭의 경우 스위프트의 클로져와 비교 할 수 밖에 없는 기능인데, 유감스럽게도 Objective-C의 블럭 문법은 클로져에 비해 좀 복잡하고 읽기 어렵다고 생각된다. 그래서 함수형 프로그래밍에서도 잘 언급 안되는 것 같고 그래서 내 경우 로컬 변수에 블럭을 할당하는 방법은 거의 쓰지 않는다. 반면에 스위프트에선 좀 복잡해 진다 싶으면 바로 클로져로 분리해 버리기도 하는 등 자주 쓰이는데 말이다.
물론 쓸 게 없어서 쓰는 잡설일 뿐이다. ;-)
typedef 로 타입으로 만들기
typedef RETURN_TYPE (^NAME)(PARAMETERS...);정의 예제(Definition Example):
typedef void (^SomeHandler)(NSError *error);구현 예제(Implementation Example):
- (void)someWorkWithCompletion:(SomeHandler)handler { ... }이름이 리턴 타입 뒤에, 즉 중간에 끼어 있기 때문에 많이 헷갈린다. -_-;
바로 Parameter Field 로 정의하기
fieldName:(RETURN_TYPE (^)(PARAMETERS...))parameterName정의 예제(Definition Example):
- (void)someMethodWithCompletion:(void (^)(NSData *data))completionHandler;구현 예제(Implementation Example):
[someClass someMethodwithCompletion:^(NSData *data) { ... }];
Property로 정의하기
RETURN_TYPE (^)(PARAMETERS...)정의 예제(Definition Example):
@property (nonatomic, strong) void (^completionHandler)(NSData *data);구현 예제(Implementation Example):
someClass.completionHandler = ^(NSData *data) { ... };프로퍼티로 정의하는 경우에도 이름이 가운데에 끼어서 좀 불안한(?) 모양세다.
변수로 생성하기
RETURN_TYPE (^BLOCK_NAME)(PARAMETER_TYPES...) = ^RETURN_TYPE(PARAMETERS...) { ... };구현 예제(Implementation Example):
void (^someBlock)(NSData *) = ^void(NSData *data) { ... }; [obj methodUsingBlock:someBlock]; [obj anotherMethodUsingBlock:someBlock];만약 블럭을 여러 곳에서 공통적으로 쓴다면 변수 등으로 정의해서 참조 할 수 있다.
보너스: 블럭 외부의 변수를 블럭 내부에서 세팅하기
Swift 클로져의 경우는 별 상관 없는데 Objective-C 블럭의 경우 외부 변수에 뭔가를 쓰는 것은 기본적으로 금지되어 있다. (즉 읽기만 가능하다.) 이를 쓰기 가능하게 풀려면 '__block
' 을 쓰려는 변수 선언 앞에 달아주면 된다. 아래 코드는 GCD Dispatch 에서 사용하는 예이다.
__block int result = 0; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ .... result = [some workAndResult]; });
잡설
리턴타입이나 인자가 없는 경우 void를 사용하면 된다는 거야 다들 알 거라 생각되어서 생략했다. C를 잘 모른다면 Objective-C를 반 밖에 모른다는 의미이니 어느 정도는 파악해 두자.블럭의 경우 스위프트의 클로져와 비교 할 수 밖에 없는 기능인데, 유감스럽게도 Objective-C의 블럭 문법은 클로져에 비해 좀 복잡하고 읽기 어렵다고 생각된다. 그래서 함수형 프로그래밍에서도 잘 언급 안되는 것 같고 그래서 내 경우 로컬 변수에 블럭을 할당하는 방법은 거의 쓰지 않는다. 반면에 스위프트에선 좀 복잡해 진다 싶으면 바로 클로져로 분리해 버리기도 하는 등 자주 쓰이는데 말이다.
물론 쓸 게 없어서 쓰는 잡설일 뿐이다. ;-)
댓글