NSThread 의 main 메소드 내부에는 어떤 것들이 있습니까?
1 ;Foundation`-[NSThread main]:
2 -> 0x7fff2594fa69 0>: push rbp
3 0x7fff2594fa6a 1>: mov rbp, rsp
4 0x7fff2594fa6d 4>: mov rax, qword ptr [rdi + 0x8]
5 0x7fff2594fa71 8>: mov rsi, qword ptr [rax + 0x20]
6 0x7fff2594fa75 12>: test rsi, rsi
7 0x7fff2594fa78 15>: je 0x7fff2594fa8e ;
8 0x7fff2594fa7a 17>: mov rdi, qword ptr [rax + 0x18]
9 0x7fff2594fa7e 21>: test rdi, rdi
10 0x7fff2594fa81 24>: je 0x7fff2594fa8e ;
11 0x7fff2594fa83 26>: mov rdx, qword ptr [rax + 0x28]
12 0x7fff2594fa87 30>: pop rbp
13 0x7fff2594fa88 31>: jmp qword ptr [rip + 0x5b02d3c2] ; (void *)0x00007fff50ba4400: objc_msgSend
14 0x7fff2594fa8e 37>: pop rbp
15 0x7fff2594fa8f 38>: ret
rdi 레지스터가 저장된 것이self이기 때문에 우리는 4줄의 어셈블리가 현재 NSThread 대상에서 8바이트를 옮기고 이 주소가 가리키는 값을 rax 레지스터에 전달하는 것이 NSThread 대상 내부의 실례적인 변수 값을 얻는 것임을 알 수 있다.그렇다면 NSThread 객체 내부에서 8바이트 오프셋된 인스턴스 변수는 무엇입니까?NSThread 객체 내부의 인스턴스 변수는 다음과 같은 방법으로 가져옵니다.
1 (lldb) po [0x600002bbe600 _ivarDescription]
2 <NSThread: 0x600002bbe600>:
3 in NSThread:
4 _private (id): <_NSThreadData: 0x600000fe0a00>
5 _bytes (unsigned char[44]): Value not representable, [44C]
6 in NSObject:
7 isa (Class): NSThread (isa, 0x7fff87b504c8)
위의 출력에서 볼 수 있듯이 NSThread 대상 내부의 실례 변수는 3개이고 편향 8바이트는 하나의 이사 바늘의 길이이다. 그러면 이때의 실례 변수는 위에서 출력한 4줄의 이다NSThreadData 객체, 즉 rax 레지스터는 지금 입니다.NSThreadData 객체의 주소입니다.
계속main의 인코딩 5줄을 보십시오. 이 줄 인코딩 은NSThreadData 객체 오프셋 32바이트의 인스턴스 변수 값은 rsi 레지스터에 지정됩니다.마찬가지로, 우리가 보기엔NSThreadData 객체 오프셋 32바이트의 인스턴스 변수는 무엇입니까?
1 po [0x600000fe0a00 _ivarDescription]
2 <_NSThreadData: 0x600000fe0a00>:
3 in _NSThreadData:
4 dict (id): <__NSDictionaryM: 0x600003edaa80>
5 name (id): @"com.apple.uikit.eventfetch-thread"
6 target (id): <UIEventFetcher: 0x6000001fc000>
7 selector (SEL): threadMain
8 argument (id): nil
9 seqNum (int): 2
10 qstate (unsigned char): Value not representable, C
11 qos (char): 33
12 cancel (unsigned char): Value not representable, C
13 status (unsigned char): Value not representable, C
14 performQ (id): nil
15 performD (NSMutableDictionary*): nil
16 attr (struct _opaque_pthread_attr_t): {
17 __sig (long): 1414022209
18 __opaque (char[56]): Value not representable, [56c]
19 }
20 tid (struct _opaque_pthread_t*): 0x600000fe0a88 -> 0x700004e45000
21 pri (double): 0.5
22 defpri (double): 0.5
23 in NSObject:
24 isa (Class): _NSThreadData (isa, 0x7fff87b504a0)
위의 출력을 통해 우리는 32 바이트의 편이가 selector의 실례 변수라는 것을 발견했다. (편이를 계산할 때 이사 바늘을 잊지 마라.) 즉, 현재rsi 레지스터 안에 selector의 값이 있다는 것이다.
main 함수 어셈블리 6행은 selector가 비어 있는지 확인하고 비어 있으면 전용 줄로 이동합니다. 즉, 인코딩 14행입니다. 이때main 함수가 창고를 지우면 종료됩니다.만약 selector에 값이 있다면,NSThreadData 객체가 24바이트 오프셋된 인스턴스 변수는 rdi 레지스터(8행)에 전달됩니다.위의 출력을 대조하면 rdi 레지스터의 값은 target 실례 변수 값이어야 합니다.9번째 줄 인코딩은 target이 비어 있는지 확인하고 빈 함수도 종료합니다.비어있지 않으면NSThreadData 대상은 40바이트의 실례 변수를 rdx 레지스터에 전송합니다. 이 때 rdx 레지스터는 argument 실례 변수의 값을 저장합니다.target이 생기고,selector가 생기고,argument가 생기면,코딩 13줄에서objc 를 호출합니다msgSend 이 방법은 [targetselector:argument]를 호출하고 실행이 끝난 후main 함수를 종료합니다.
요약:
1 NSThread를 만들 때 target이나 selector를 지정하지 않으면main 함수가 바로 출시됩니다.
2 모두 지정하면main 함수는 [target selector:argument]를 호출하여 실행이 끝난 후에 종료합니다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.