IOS RunLoop 의 이벤트 순환 메커니즘 분석
Timer/Source 0 이 벤트 를 처리 하 겠 다 는 알림 을 보 냅 니 다.
Source 0 이벤트 처리
Source 1 이 처리 할 것 이 있 으 면,이 때 는 go to 문장의 실현 을 통 해 코드 논리의 도약 을 하고,깨 우 는 것 을 처리 하 는 것 은 받 은 메시지 입 니 다.
Source 1 이 처리 하지 않 으 면 스 레 드 는 휴면 하고 관찰자 에 게 알림 을 보 냅 니 다.
그 다음 에 스 레 드 는 한 사용자 상태 에서 커 널 상태 로 전환 하고 휴면 한 다음 에 깨 우 기 를 기다 리 고 깨 우 는 조건 은 약 세 가 지 를 포함한다.
1、Source1
2.타이머 이벤트
3.외부 수 동 각성
스 레 드 가 깨 어 난 후에 도 관찰자 에 게 알 리 고 깨 어 날 때 받 은 메 시 지 를 처리 해 야 합 니 다.
Timer/Source 0 이 벤트 를 처리 할 알림 의 발송 으로 돌아 가기
그리고 위 절 차 를 다시 진행 합 니 다.이것 이 바로 RunLoop 의 이벤트 순환 체제 입 니 다.
내부 코드 논리 정 리 는 다음 과 같다.
/// DefaultMode
void CFRunLoopRun(void) {
CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false);
}
/// Mode , RunLoop
int CFRunLoopRunInMode(CFStringRef modeName, CFTimeInterval seconds, Boolean stopAfterHandle) {
return CFRunLoopRunSpecific(CFRunLoopGetCurrent(), modeName, seconds, returnAfterSourceHandled);
}
/// RunLoop
int CFRunLoopRunSpecific(runloop, modeName, seconds, stopAfterHandle) {
/// modeName mode
CFRunLoopModeRef currentMode = __CFRunLoopFindMode(runloop, modeName, false);
/// mode source/timer/observer, 。
if (__CFRunLoopModeIsEmpty(currentMode)) return;
/// 1. Observers: RunLoop loop。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopEntry);
/// , loop
__CFRunLoopRun(runloop, currentMode, seconds, returnAfterSourceHandled) {
Boolean sourceHandledThisLoop = NO;
int retVal = 0;
do {
/// 2. Observers: RunLoop Timer 。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeTimers);
/// 3. Observers: RunLoop Source0 ( port) 。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeSources);
/// block
__CFRunLoopDoBlocks(runloop, currentMode);
/// 4. RunLoop Source0 ( port) 。
sourceHandledThisLoop = __CFRunLoopDoSources0(runloop, currentMode, stopAfterHandle);
/// block
__CFRunLoopDoBlocks(runloop, currentMode);
/// 5. Source1 ( port) ready , Source1 。
if (__Source0DidDispatchPortLastTime) {
Boolean hasMsg = __CFRunLoopServiceMachPort(dispatchPort, &msg)
if (hasMsg) goto handle_msg;
}
/// Observers: RunLoop (sleep)。
if (!sourceHandledThisLoop) {
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeWaiting);
}
/// 7. mach_msg mach_port 。 , 。
/// • port Source 。
/// • Timer
/// • RunLoop
/// •
__CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort) {
mach_msg(msg, MACH_RCV_MSG, port); // thread wait for receive msg
}
/// 8. Observers: RunLoop 。
__CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopAfterWaiting);
/// , 。
handle_msg:
/// 9.1 Timer , Timer 。
if (msg_is_timer) {
__CFRunLoopDoTimers(runloop, currentMode, mach_absolute_time())
}
/// 9.2 dispatch main_queue block, block。
else if (msg_is_dispatch) {
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
}
/// 9.3 Source1 ( port) ,
else {
CFRunLoopSourceRef source1 = __CFRunLoopModeFindSourceForMachPort(runloop, currentMode, livePort);
sourceHandledThisLoop = __CFRunLoopDoSource1(runloop, currentMode, source1, msg);
if (sourceHandledThisLoop) {
mach_msg(reply, MACH_SEND_MSG, reply);
}
}
/// Loop block
__CFRunLoopDoBlocks(runloop, currentMode);
if (sourceHandledThisLoop && stopAfterHandle) {
/// loop 。
retVal = kCFRunLoopRunHandledSource;
} else if (timeout) {
///
retVal = kCFRunLoopRunTimedOut;
} else if (__CFRunLoopIsStopped(runloop)) {
///
retVal = kCFRunLoopRunStopped;
} else if (__CFRunLoopModeIsEmpty(runloop, currentMode)) {
/// source/timer/observer
retVal = kCFRunLoopRunFinished;
}
/// ,mode ,loop , loop。
} while (retVal == 0);
}
/// 10. Observers: RunLoop 。
__CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
}
실제로 RunLoop 은 이러한 함수 이 고 그 내 부 는 do-while 순환 이다.CFRunLoopRun()을 호출 하면 스 레 드 는 이 순환 에 머 물 러 있 습 니 다.시간 이 초과 되 거나 수 동 으로 멈 출 때 까지 이 함수 가 되 돌아 올 수 있 습 니 다.이러한 문제 가 있 습 니 다.우리 가 app 을 클릭 하면 프로그램 이 시작 되 고 프로그램 이 실행 되 며 프로그램 이 죽 는 과정 까지 시스템 에 무슨 일이 일 어 났 습 니까?
실제 적 으로 main 함 수 를 호출 한 후에 UIApplicationMain 함 수 를 호출 합 니 다.이 함수 내부 에서 메 인 스 레 드 의 RunLoop 을 시작 한 다음 에 일련의 처 리 를 거 쳐 최종 적 으로 메 인 스 레 드 의 RunLoop 은 휴면 상태 에 있 을 것 입 니 다.그리고 우 리 는 이때 화면 을 클릭 하면 Source 1 로 전환 하여 메 인 스 레 드 를 깨 울 것 입 니 다.그리고 우리 가 프로그램 을 죽 일 때 RunLoop 의 종 료 를 호출 하고 관찰자 에 게 알림 을 보 냅 니 다.
총 결 도 를 찾 아 기억 을 돕 기:
이상 은 IOS RunLoop 의 이벤트 순환 체 제 를 분석 하 는 상세 한 내용 입 니 다.IOS RunLoop 의 이벤트 순환 체제 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
IOS에서 ReplayKit 및 RTC 사용 방법응용된 소리와 아나운서의 소리를 포함한다.이 두 가지 수요를 감안하여 우리는 스크린 공유를 하는 생방송에 필요한 미디어 흐름을 간단하게 분석할 수 있다. 만약 우리가 Audio App과 Audio Mic를 두 개의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.