본문 바로가기
프로그래밍 놀이터/iOS

[Effective Objective-C] #39 핸들러 블록을 사용해 코드가 여러 개로 나뉘는 것을 막으라

by 돼지왕 왕돼지 2017. 10. 3.
반응형

 [Effective Objective-C] #39 핸들러 블록을 사용해 코드가 여러 개로 나뉘는 것을 막으라


출처 : Effective Objective-C

completion block, completion handler, conform, Enqueue, network patcher, nsnotificationcenter, system watchdog, [Effective Objective-C] #39 핸들러 블록을 사용해 코드가 여러 개로 나뉘는 것을 막으라, 강제 종료, 객체 연관, 네트워크 페처, 델리게이트 단점, 델리게이트 프로토콜, 메서드 전달, 메인 스레드, 블록, 성공 실패 블록, 스위칭, 시스템 와치독, 애플 api, 에러, 완료 핸들러, 유연, 인스턴스, 장점, 콜백, 하나의 완료 블록, 핸들러 블록


-

특정 상황에서 앱이 특정 시간 동안 응답하지 않으면 자동으로 종료될 수 있다.

특히 iOS 앱은 반드시 종료된다.

시스템 와치독(system watchdog)은 특정 시간 동안 메인 스레드가 중단된 앱은 강제로 종료시킨다.



-

비동기 메서드를 쓰면 일을 끝냈을 때 완료 사실을 알고 싶어 하는 것들에 완료 사실을 알려주는 방법이 필요하다.

이를 할 수 있는 방법이 몇 가지 있다.

일반적으로 쓰는 방법은 객체가 따를 수 있는(conform) 델리게이트 프로토콜을 이용하는 것이다.

델리게이트 객체는 비동기 작업의 완료 같은 적절한 이벤트가 발생하면 알림을 받을 수 있다.



-

블록을 이용하면 같은 일을 더 명확한 방법으로 할 수 있다.

블록은 이와 같은 API 를 더 엄격한 방법으로 사용할 수 있다.

그리고 사용자도 훨씬 깔끔한 방법으로 API 를 사용할 수 있다.

그 방법은 바로 완료 핸들러(completion handler)로 사용할 블록 타입을 정의해 메서드에 직접 전달하는 것이다.



-

델리게이트 방법의 단점은 서로 다른 데이터를 다운로드하는 다수의 네트워크 페처를 사용하는 클래스라면,

콜백하는 네트워크 페처에 따라 delegate 메서드에서 바꿔서 처리해야 한다는 것이다.



-

블록 방법의 장점은 네트워크 페처를 저장할 필요가 없다는 것.

그리고 네트워크 페처에 따른 스위칭도 필요하지 않다.

각 완료 핸들러의 비지니스 로직이 각 페처와 함께 정의되어 있다.



-

최신 블록 기반 API 가 에러 처리를 위해 블록을 사용한다.


두 가지 방법으로 사용할 수 있다.

첫 번째 방법은 두 개의 핸들러가 성공했을 경우와 실패했을 경우를 위해 각각 사용될 수 있다.

두번째 방법으로는 하나의 완료 블록(completion block)으로 성공한 경우와 실패한 경우를 모두 처리하도록 하는 것이다.



-

하나의 완료 블록 코드의 단점은 모든 로직을 한곳에 넣는다는 것이다.

블록이 길어지고 복잡해질 수 있다.

그러나 단일 블록 방법의 장점은 매우 유연하다는 것이다.



-

성공과 실패에 대한 로직을 한 블록에 넣을 때 생기는 또 다른 장점은 성공한 응답을 처리하는 도중 에러가 발견된 때에 발휘된다.

이 같은 에러는 네트워크 페처에서 발생한 에러를 처리하는 것과 동일하게 다루어져야 한다.

이 같이 단일 블록에 로직이 모두 모여 있으면 데이터에 에러가 있을 때 처리할 수 있을 뿐 아니라 네트워크 페처에서 발생한 에러도 같이 처리할 수 있다.



-

저자는 전체적으로 성공과 실패 처리를 핸들러 블록 하나에 두는 것을 추천한다.

이 방법은 또한 애플 API 에서 사용하는 방법이다.



-

핸들러 기반 API 를 작성할 때 고려해야 할 것이 또 있는데,

몇몇 코드는 반드시 특정 스레드에 동작해야 한다는 사실이다.

예를 들면 코코아와 코코아 터치 둘 다 UI 작업은 메인 스레드에서 해야 한다.


그렇기 때문에 핸들러 기반 API 사용자는 핸들러를 실행할 큐를 신중하게 결정해야 한다.

그런 API 중 하나가 NSNotificationCenter 다.

메서드를 하나 가졌는데 이 메서드로 알림 센터에서 알림을 받기 위해 등록할 수 있다.

나중에 알림 센터에서 등록한 블록이 실행되어 특정 알림을 받을 수 있다.

블록을 등록할 큐를 지정할 수 있지만 꼭 지정할 필요는 없다.

큐를 지정하지 않으면 기본 행동이 호출된다.

그리고 블록은 알림을 발생시킨 스레드에서 실행된다.




기억할 점


-

객체를 생성하는 곳에 핸들러의 비지니스 로직을 인라인으로 같이 선언하는 게 유용하다면 핸들러 블록을 이용해 하라.



-

핸들러 블록은 델리게이트와는 다르게 직접 객체에 연관될 수 있는 장점이 있다.

델리게이트를 사용할 때 관찰해야 할 인스턴스가 여러 개이면 인스턴스에 따라 바꾸어 처리해야 한다.



-

핸들러 블록을 사용하는 API 를 설계할 때 블록이 들어갈(enqueue) 큐를 API 파라미터로 전달하라.




반응형

댓글