NSDefaultRunLoopMode 대 NSRunLoopCommonModes


114

나는 큰 파일 뒤에 다운로드를 시도 할 때마다 UIScrollView, MPMapView또는 무언가를, 다운로드 프로세스는 최대한 빨리 아이폰의 터치 스크린으로 중단됩니다. 고맙게도 Jörn 의 멋진 블로그 게시물 NSRunLoopCommonModes은 연결 을 위해 사용하는 대체 옵션을 제안 합니다.

그러면 NSDefaultRunLoopMode와 NSRunLoopCommonModes의 두 가지 모드에 대해 자세히 살펴볼 수 있지만 사과 문서는 다음과 같이 설명하는 것 외에는 친절하게 설명하지 않습니다.

NSDefaultRunLoopMode

NSConnection 객체 이외의 입력 소스를 처리하는 모드입니다. 가장 일반적으로 사용되는 실행 루프 모드입니다.

NSRunLoopCommonModes

이 값을 모드로 사용하여 실행 루프에 추가 된 개체는 "공통"모드 집합의 구성원으로 선언 된 모든 실행 루프 모드에서 모니터링됩니다. 자세한 내용은 CFRunLoopAddCommonMode의 설명을 참조하십시오.

CFRunLoopAddCommonMode

소스, 타이머 및 관찰자는 하나 이상의 실행 루프 모드에 등록되고 실행 루프가 이러한 모드 중 하나에서 실행 중일 때만 실행됩니다. 공통 모드는 이러한 모드에서 공유하는 소스, 타이머 및 관찰자 세트를 정의 할 수있는 실행 루프 모드 세트입니다. 예를 들어 각 특정 런 루프 모드에 소스를 등록하는 대신 런 루프의 공통 의사 모드에 한 번 등록 할 수 있으며 공통 모드 세트의 각 런 루프 모드에 자동으로 등록됩니다. 마찬가지로 공통 모드 세트에 모드가 추가되면 공통 의사 모드에 이미 등록 된 소스, 타이머 또는 관찰자가 새로 추가 된 공통 모드에 추가됩니다.

누구든지 인간의 언어로 두 가지를 설명해 주시겠습니까?

답변:


204

실행 루프는 시스템이 대기중인 스레드를 깨워 비동기 이벤트를 관리 할 수 ​​있도록하는 메커니즘입니다. 일반적으로 스레드를 실행할 때 (메인 스레드를 제외하고) 실행 루프에서 스레드를 시작하거나 시작하지 않는 옵션이 있습니다. 스레드가 외부 이벤트와 상호 작용하지 않고 타이머없이 일종의 장기 실행 작업을 실행하는 경우 실행 루프가 필요하지 않지만 스레드가 들어오는 이벤트에 응답해야하는 경우 실행 루프에 연결해야합니다. 새 이벤트가 도착하면 스레드를 깨 웁니다. 이것은 NSURLConnection(네트워크에서) 들어오는 이벤트에서만 깨어나 기 때문에 생성 된 스레드 의 경우입니다 .

각 스레드는 여러 실행 루프에 연결되거나 다른 모드에서 작동하도록 설정할 수있는 특정 실행 루프에 연결될 수 있습니다. "실행 루프 모드"는 특정 이벤트를 전달하거나 나중에 전달하기 위해 수집 할시기에 대한 몇 가지 규칙을 설정하기 위해 OS에서 사용하는 규칙입니다.

일반적으로 모든 실행 루프는 입력 이벤트를 관리하는 기본 방법을 설정하는 "기본 모드"로 설정됩니다. 예 : 마우스 끌기 (Mac OS) 또는 터치 (iOS) 이벤트가 발생하면이 런 루프의 모드가 이벤트 추적으로 설정됩니다. 이것은 스레드가 새 네트워크 이벤트에서 깨어나지 않지만 이러한 이벤트는 사용자 입력 이벤트가 종료되고 실행 루프가 다시 기본 모드로 설정 될 때 전달된다는 것을 의미합니다. 분명히 이것은 백그라운드 이벤트 대신 사용자 이벤트에 우선 순위를 부여하기 위해 OS 설계자가 선택한 것입니다.

NSURLConnection를 사용 하여 스레드 의 실행 루프 모드를 변경하기로 결정한 경우 특정 기본 실행 루프가 아닌 scheduleInRunLoop:forModes:특수 실행 루프 모드에 스레드를 할당 할 수 있습니다 . 호출 된 특수 의사 모드 NSRunLoopCommonModes는 이벤트 추적을 포함한 많은 입력 소스에서 사용됩니다. 예를 들어 NSURLConnection의 인스턴스를 공통 모드에 할당 한다는 것은 해당 이벤트를 "기본 모드"외에도 "추적 모드"에 연결하는 것을 의미합니다. 스레드를 연결하는 한 가지 장점 / 단점은 NSRunLoopCommonModes스레드가 터치 이벤트에 의해 차단되지 않는다는 것입니다.

공통 모드에 새로운 모드를 추가 할 수 있지만 이것은 상당히 낮은 수준의 작업입니다.

몇 가지 메모를 추가하여 닫고 싶습니다.

  • 일반적으로 테이블보기와 함께 네트워크에서 다운로드 한 이미지 또는 썸네일 세트를 사용해야합니다. 테이블 뷰가 스크롤되는 동안 네트워크에서 이러한 이미지를 다운로드하면 사용자 경험이 향상 될 수 있다고 생각할 수 있지만 (스크롤하는 동안 이미지를 볼 수 있기 때문에) 스크롤의 유동성이 크게 저하 될 수 있으므로 이점이 없습니다. 이 예에서는 NSURLConnection런 루프를 사용해서는 안됩니다. UIScrollView델리게이트 메소드 를 사용하여 스크롤이 종료되는시기를 감지 한 다음 테이블을 업데이트하고 네트워크에서 새 항목을 다운로드하는 것이 좋습니다 .

  • 실행 루프 관리 문제로부터 코드를 "보호"하는 데 도움이되는 GCD 사용을 고려할 수 있습니다. 위의 예에서 사용자 지정 직렬 대기열에 네트워크 요청을 추가하는 것을 고려할 수 있습니다.


9
친애하는 Viggio24,이 깨끗하고 정확한 설명에 감사드립니다. API 가이드에 귀하의 의견을 포함하도록 Apple에 요청합니다. ;)
Stkim1 2011-08-29

7
viggio24 의 대답은 완벽합니다. 관심있는 사람들을 위해 WWDC 2010의 세션 208 (iPhone OS 용 네트워크 앱, 2 부) 에 실행 루프에 대한 소개가 포함되어 있음을 지적합니다 . 관심이 있으시면보세요. 도움이 되었기를 바랍니다.
Lorenzo B

19
나 자신을위한 메모 : NSRunLoopCommonModes에서 스크롤하는 동안 타이머 이벤트를 허용합니다 UIScrollView. NSDefaultRunLoopMode스크롤하는 동안 타이머를 방지합니다.
eonil 2013 년

2
스크롤 뷰 업데이트에 대한 댓글이 매우 도전적인 주제를 언급했기 때문에 매우 흥미로 웠습니다. 이것에 대한 자세한 내용을 추가하기 위해 : NSURLConnection에 대한 모드를 설정하면 델리게이트 콜백 실행에만 영향을 미칩니다. 여기에서 scrollView를 업데이트하면 성능 문제가 발생할 수 있다는 것을 알고 있지만 왜 이런 일이 발생합니까? 대답이 그림을 메모리에로드해야한다는 것이라면 배경의 그래픽 컨텍스트에 작성하여이를 수행하고이 작업을 수행 한 후 뷰 주 스레드 레이어를 업데이트 할 수 있습니다. 이게 합리적으로 들립니까?
nebillo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.