'블럭코딩'에 해당되는 글 1건

  1. 2013.10.25 Objective-C 에서 block방식으로 비동기처리하기.

인류문명의 발달은 잉여노동력 그리고 적절한 환경에 의한 결과라는 제레미다이아몬드라는 유명한 아저씨의 주장이 요 며칠간 가깝게 다가왔다.

지금 마치 내상황이 잉여노동력(할일없음) + 적절한 환경(프로젝트 끝나감) 이므로 저아저씨 말대로라면 뭔라도 해야 될 상황이다.


프로젝트는 슬슬 끝나가고 할일은 없고.. 인터넷 서핑도 하루이틀이지.. 

잉여력이 넘치고 넘치던 찰나 결국 남는 잉여력을 소스코드를 이쁘게 고치는데 사용키로 했다.


지금까지 딜리게이트을 남발하면서 막개발을 해 왔는데 이번기회에 iOS5부터인가 지원되지 시작한 blocks비동기처리 방식를 써볼까? 라는 생각이 든것이다.


이제까지 문법자체가 생소해서 쓰고 싶지 않았는데 시계바늘을 본드에 붙여놓은듯 시간이 가질 않으니 어쩔수 없다.

결과적으론 익숙해지는데 조금 시간이 걸렸으나 한번 적용해보니 코드량이 상당히 줄어드는걸 체감했다.

더이상 딜리게이트를 남발하지 않으리...


그럼 일단 block방식으로 코딩하기 위한 문법부터 살펴보자.


블럭구문 기본적인 선언방법

^(파라메터,...) {

    //실행로직

};

 

블럭구문을 대입할 경우의 코딩

반환값 (^변수명)(파라메터,...) = ^(임시 파라메터...) {

    //실행로직

};


여기까지만 보면 어떻게 하라는 얘기인지 모를것이다. 직접 짜보자.


블럭구문으로 test라는 함수작성

int (^test)(int) = ^(int x) {

    return x + x;

};

 

// 결과출력

NSLog(@"%d", test(10));



블럭구문을 typedef로 정의할땐 이렇게 한다. 일반적으로 사용하는 패턴이므로 숙지해 두자.

typedef 반환값 (^변수명)(파라메터,...) 


블럭구문내에 변수사용하기.

__block를 변수앞에 붙이면 블럭구문내에서 값변경이 가능하다.

물론 붙이지 않아도 참조는 가능.


__block int x = 300;

void (^print)(void) = ^(void) {

    x++;

    NSLog(@"%d", x);

};


자.. 여기까지는 기본적인 사항이고 실제로 하고싶은 블럭구문을 메소드에 넘겨주는 걸 해보자.

- (void)example:(double (^)(int, int))func {

int i = 3;

int j = 4;


if(func(i,j) > 5) {

  //처리1...

}else {

  //처리2...

}

}


이런식으로 쓴다. 파라메터로 받은 블럭구분 결과로 처리가 가능하다. 이전엔 이와같은 처리를 딜리게이트로 해결했었다.


실제 호출될 경우에 블록구문내 처리를 하도록 코딩하자.

[self example:^(int n1, int n2) {

//실행처리

    return i+j;

}];


자 여기서 아까 언급했던 typedef 를 상기해보자.

그렇다 메소드에 넘기는 블럭구문을 간단히 정의하여 메소드길이를 줄일수 있다.


//이렇게 정의한 다음..

typedef double (^calcHandler)(int a, int b);



//이렇게 바꾸어 쓸수 있다.

- (void)example:(calcHandler)func {

...

}


딜리게이트의 경우는 프로토콜 정의해주고 그걸 받는쪽에서 위임받아서 처리해주는 구문까지 해야하므로 상당히 코딩량이 많아지는데 반해서 블럭은 상당히 코드를 줄어든다.


조금 설명이 부족한거 같아 한가지 예를 더 들어보자. 

어떤 특정 메소드를 실행이 끝난뒤 후처리를 해주는 메소드를 만들어보자.

블록구문이 사용된 우리가 흔히보는 메소드이다.

[self.navigationController dismissViewControllerAnimated:(BOOL) completion:^{

        //TODO: 

        //화면이 닫힌후 후처리.

    }];

    


먼저 블럭구문부터 관찰해보면 반환값, 파라메터도 없는 블럭이다.

^{ 

//TODO: 

}


위와 같은 처리를 하는 calcTime라는 이름의 메소드를 만들어보자. 그리고 이 메소드가 실행이 완료되면 실행되는 블럭을 만들어 보자.


우선 메소드 선언.

- (void)calcTime:(void ^(void)handler;


그리고 메소드 정의

- (void)calcTime:(void ^(void)handler {


//무쟈게 오래걸리는 처리가 있다고 치자..

//...

//처리가 다 끝난부분에서 블럭구문을 실행하게 한다.

handler();

}

    

    

실제 호출하여 사용할때에는..

[self calcTime:^{

//이메소드 끝날때 처리할 내용 코딩..

}];



써놓고 보니 별 내용없네.. 

테스트하면서 코딩한게 아니라서 소스에 오류가 있을수 있으므로 참고하시길..


Posted by 악당잰 트랙백 0 : 댓글 0

댓글을 달아 주세요