서버에 이미지를 요청하여 화면에 뿌려주는 작업을 진행 중에 UITableView와 NSURLConnection의 동기화 문제로 고민하게 되었다

테이블뷰가 스크롤과 네트워크 작업은 서로 메인 Thread에서 진행되기 때문이다.

원하는 결과는 스크롤을 하면서도 화면에 출력될때 이미지를 받아올수 있어야 하기 때문에 인터넷을 찾아본 결과 의외로 간단했다

해답은 NSRunLoop의 설정을 변경해주어야 했었다.

아래 일반적으로 사용하는 NSURLConnection이다.

NSURLConnection * mConnection = [[NSURLConnection alloc] initWithRequest:aRequest delegate:self startImmediately:NO];
self.connection = mConnection;
[mConnection release];

[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];

위에서 보면 connection에 ScheduleInRunLoop:forMode: 메소드를 통해 현재 RunLoop에 Connection을 등록하는 부분이 있다.

여기서 Mode를 보면 NSDefaultRunLoopMode인데 이 부분이 중요했다.

우선 RunLoop에 connection을 연결하면 네트워크 요청 후 응답때까지 RunLoop에서 대기하는 용도로 사용한다. 보통 Opreation이나 Thread같은 경우

main이 실행되고 나면 역활이 끝나기 때문에 비동기적으로 대기하고 있으려면 저렇게 RunLoop에 등록해 두어야 한다.

하지만 기본적으로 사용하는 NSDefaultRunLoopMode을 사용하게 되면 테이블 스크롤 이벤트와 우선순위에서 낮아서 그런지 몰라도 UI Event가 우선 실행되고 Connection응답이 나중에 처리 된다.

이 현상을 수정하기 위해 Mode의 값을 변경하였다.

NSDefaultRunLoopMode -> NSRunLoopCommonModes

RunLoop 모드가 딱 두가지 밖에 없으므로 찾기에 어렵지 않을 것이다.

마지막으로 connection이 종료 후 작업을 마무리할때는 connection을 RunLoop스케줄에서 해제를 해주어야 한다.

[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[self.connection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

+ Recent posts