下面是NSThread start方法的汇编码:

 1  1 1 ;Foundation`-[NSThread start]:
2 2 2 -> 0x7fff2594f47f <+0>: push rbp
3 3 3 0x7fff2594f480 <+1>: mov rbp, rsp
4 4 4 0x7fff2594f483 <+4>: push r15
5 5 5 0x7fff2594f485 <+6>: push r14
6 6 6 0x7fff2594f487 <+8>: push r12
7 7 7 0x7fff2594f489 <+10>: push rbx
8 8 8 0x7fff2594f48a <+11>: mov r14, rsi
9 9 9 0x7fff2594f48d <+14>: mov r15, rdi
10 10 10 0x7fff2594f490 <+17>: mov rax, qword ptr [rdi + 0x8];rid存储self,这里获取NSThread对象里面的_NSThreadData对象
11 11 11 0x7fff2594f494 <+21>: mov cl, byte ptr [rax + 0x37]
12 12 12 0x7fff2594f497 <+24>: cmp cl, 0xd;通过_NSThread对象里面的实例变量判断线程是否已经被启动过
13 13 13 0x7fff2594f49a <+27>: jae 0x7fff2594f579 ; <+250>;如果已经被启动过了,跳转到<+250>处,也就是73行处抛出异常
14 14 14 0x7fff2594f4a0 <+33>: mov byte ptr [rax + 0x37], 0xd;回写启动过标志到_NSThreadData对象
15 15 15 0x7fff2594f4a4 <+37>: mov rbx, qword ptr [r15 + 0x8]
16 16 16 0x7fff2594f4a8 <+41>: cmp byte ptr [rbx + 0x36], 0x0
17 17 17 0x7fff2594f4ac <+45>: je 0x7fff2594f4b7 ; <+56>
18 18 18 0x7fff2594f4ae <+47>: mov byte ptr [rbx + 0x37], 0xf
19 19 19 0x7fff2594f4b2 <+51>: jmp 0x7fff2594f570 ; <+241>
20 20 20 0x7fff2594f4b7 <+56>: cmp byte ptr [rip + 0x6220e832], 0x0 ; _NSCStringCharToUnicharTable + 7 判断当前应用是否在多线程模式
21 21 21 0x7fff2594f4be <+63>: jne 0x7fff2594f4fa ; <+123>是的话跳转到<+123>,也就是34行处,不会发通知NSWillBecomeMultiThreadedNotification
22 22 22 0x7fff2594f4c0 <+65>: mov byte ptr [rip + 0x6220e829], 0x1 ; _NSCStringCharToUnicharTable + 7 如果不是多线程模式,回写标志1,发通知NSWillBecomeMultiThreadedNotification
23 23 23 0x7fff2594f4c7 <+72>: mov rdi, qword ptr [rip + 0x621f72c2] ; (void *)0x00007fff87b4f758: NSNotificationCenter
24 24 24 0x7fff2594f4ce <+79>: mov rsi, qword ptr [rip + 0x621ee9d3] ; "defaultCenter"
25 25 25 0x7fff2594f4d5 <+86>: mov rbx, qword ptr [rip + 0x5b02d974] ; (void *)0x00007fff50ba4400: objc_msgSend
26 26 26 0x7fff2594f4dc <+93>: call rbx
27 27 27 0x7fff2594f4de <+95>: mov rsi, qword ptr [rip + 0x621ef763] ; "postNotificationName:object:userInfo:"
28 28 28 0x7fff2594f4e5 <+102>: lea rdx, [rip + 0x5b046e3c] ; @"NSWillBecomeMultiThreadedNotification"
29 29 29 0x7fff2594f4ec <+109>: mov rdi, rax
30 30 30 0x7fff2594f4ef <+112>: xor ecx, ecx
31 31 31 0x7fff2594f4f1 <+114>: xor r8d, r8d
32 32 32 0x7fff2594f4f4 <+117>: call rbx
33 33 33 0x7fff2594f4f6 <+119>: mov rbx, qword ptr [r15 + 0x8]
34 34 34 0x7fff2594f4fa <+123>: mov al, byte ptr [rbx + 0x35]
35 35 35 0x7fff2594f4fd <+126>: test al, al
36 36 36 0x7fff2594f4ff <+128>: je 0x7fff2594f523 ; <+164>
37 37 37 0x7fff2594f501 <+130>: add rbx, 0x48
38 38 38 0x7fff2594f505 <+134>: cmp al, -0x1
39 39 39 0x7fff2594f507 <+136>: movzx eax, al
40 40 40 0x7fff2594f50a <+139>: mov ecx, 0x15
41 41 41 0x7fff2594f50f <+144>: cmovne ecx, eax
42 42 42 0x7fff2594f512 <+147>: movsx esi, cl
43 43 43 0x7fff2594f515 <+150>: mov rdi, rbx
44 44 44 0x7fff2594f518 <+153>: xor edx, edx
45 45 45 0x7fff2594f51a <+155>: call 0x7fff25af352c ; symbol stub for: pthread_attr_set_qos_class_np
46 46 46 0x7fff2594f51f <+160>: mov rbx, qword ptr [r15 + 0x8]
47 47 47 0x7fff2594f523 <+164>: lea r12, [rbx + 0x88]
48 48 48 0x7fff2594f52a <+171>: add rbx, 0x48
49 49 49 0x7fff2594f52e <+175>: mov rdi, r15
50 50 50 0x7fff2594f531 <+178>: call qword ptr [rip + 0x5b02d929] ; (void *)0x00007fff50bbec60: objc_retain
51 51 51 0x7fff2594f537 <+184>: lea rdx, [rip + 0x96] ; __NSThread__start__
52 52 52 0x7fff2594f53e <+191>: mov rdi, r12
53 53 53 0x7fff2594f541 <+194>: mov rsi, rbx
54 54 54 0x7fff2594f544 <+197>: mov rcx, rax
55 55 55 0x7fff2594f547 <+200>: call 0x7fff25af3574 ; symbol stub for: pthread_create
56 56 56 0x7fff2594f54c <+205>: test eax, eax
57 57 57 0x7fff2594f54e <+207>: je 0x7fff2594f570 ; <+241>
58 58 58 0x7fff2594f550 <+209>: mov ebx, eax
59 59 59 0x7fff2594f552 <+211>: mov rdi, r15
60 60 60 0x7fff2594f555 <+214>: mov rsi, r14
61 61 61 0x7fff2594f558 <+217>: call 0x7fff2593542b ; _NSMethodExceptionProem
62 62 62 0x7fff2594f55d <+222>: lea rdi, [rip + 0x5b046d84] ; @"%@: Thread creation failed with error %d"
63 63 63 0x7fff2594f564 <+229>: mov rsi, rax
64 64 64 0x7fff2594f567 <+232>: mov edx, ebx
65 65 65 0x7fff2594f569 <+234>: xor eax, eax
66 66 66 0x7fff2594f56b <+236>: call 0x7fff25931294 ; NSLog
67 67 67 0x7fff2594f570 <+241>: pop rbx
68 68 68 0x7fff2594f571 <+242>: pop r12
69 69 69 0x7fff2594f573 <+244>: pop r14
70 70 70 0x7fff2594f575 <+246>: pop r15
71 71 71 0x7fff2594f577 <+248>: pop rbp
72 72 72 0x7fff2594f578 <+249>: ret
73 73 73 0x7fff2594f579 <+250>: mov rbx, qword ptr [rip + 0x621f7150] ; (void *)0x00007fff87b502e8: NSString
74 74 74 0x7fff2594f580 <+257>: mov rdi, r15
75 75 75 0x7fff2594f583 <+260>: mov rsi, r14
76 76 76 0x7fff2594f586 <+263>: call 0x7fff2593542b ; _NSMethodExceptionProem
77 77 77 0x7fff2594f58b <+268>: mov rsi, qword ptr [rip + 0x621ee3fe] ; "stringWithFormat:"
78 78 78 0x7fff2594f592 <+275>: lea rdx, [rip + 0x5b046d2f] ; @"%@: attempt to start the thread again"
79 79 79 0x7fff2594f599 <+282>: mov r14, qword ptr [rip + 0x5b02d8b0] ; (void *)0x00007fff50ba4400: objc_msgSend
80 80 80 0x7fff2594f5a0 <+289>: mov rdi, rbx
81 81 81 0x7fff2594f5a3 <+292>: mov rcx, rax
82 82 82 0x7fff2594f5a6 <+295>: xor eax, eax
83 83 83 0x7fff2594f5a8 <+297>: call r14
84 84 84 0x7fff2594f5ab <+300>: mov rdi, qword ptr [rip + 0x621f717e] ; (void *)0x00007fff87a91f48: NSException
85 85 85 0x7fff2594f5b2 <+307>: mov rcx, qword ptr [rip + 0x5b02cf27] ; (void *)0x00007fff80637d60: NSInvalidArgumentException
86 86 86 0x7fff2594f5b9 <+314>: mov rdx, qword ptr [rcx]
87 87 87 0x7fff2594f5bc <+317>: mov rsi, qword ptr [rip + 0x621ee565] ; "exceptionWithName:reason:userInfo:"
88 88 88 0x7fff2594f5c3 <+324>: mov rcx, rax
89 89 89 0x7fff2594f5c6 <+327>: xor r8d, r8d
90 90 90 0x7fff2594f5c9 <+330>: call r14
91 91 91 0x7fff2594f5cc <+333>: mov rdi, rax
92 92 92 0x7fff2594f5cf <+336>: call 0x7fff25af332e ; symbol stub for: objc_exception_throw

上面的汇编代码总共分4部分:

第一部分:第10行到第13行,判断是当前的NSThread是否被启动过,如果已经启动过再次启动,就会抛出异常

第二部分:第14到第32行,启动线程前会判断当前应用使用已经是多线程状态了,如果还不是,就抛出通知NSWillBecomeMultiThreadedNotification;如果是不会抛出通知

第三部分:第33行到55行,调用pthread_create函数创建一个线程,并将__NSThread__start__函数作为pthread_create函数的第三个参数传递进去,而这个参数是线程的入口函数

第四部分:第55行到92行,主要是抛出两个异常,一个是线程创建失败异常,一个是线程重复启动异常。

上面的分析中,有一个__NSThread_start__函数,它是线程的入口函数,我们继续看看它里面的实现,汇编代码如下:

  1 Foundation`__NSThread__start__:
2 -> 0x7fff2594f5d4 <+0>: push rbp
3 0x7fff2594f5d5 <+1>: mov rbp, rsp
4 0x7fff2594f5d8 <+4>: push r15
5 0x7fff2594f5da <+6>: push r14
6 0x7fff2594f5dc <+8>: push r13
7 0x7fff2594f5de <+10>: push r12
8 0x7fff2594f5e0 <+12>: push rbx
9 0x7fff2594f5e1 <+13>: sub rsp, 0x228
10 0x7fff2594f5e8 <+20>: mov r15, rdi
11 0x7fff2594f5eb <+23>: mov rax, qword ptr [rip + 0x5b02d3ae] ; (void *)0x00007fff89cb95c0: __stack_chk_guard
12 0x7fff2594f5f2 <+30>: mov rax, qword ptr [rax]
13 0x7fff2594f5f5 <+33>: mov qword ptr [rbp - 0x30], rax
14 0x7fff2594f5f9 <+37>: lea rdx, [rip + 0xfad] ; __NSFinalizeThreadData
15 0x7fff2594f600 <+44>: mov esi, 0xbc614e
16 0x7fff2594f605 <+49>: mov edi, 0x1d
17 0x7fff2594f60a <+54>: call 0x7fff25af289c ; symbol stub for: _CFSetTSD
18 0x7fff2594f60f <+59>: mov edi, 0x1c
19 0x7fff2594f614 <+64>: mov rsi, r15
20 0x7fff2594f617 <+67>: xor edx, edx
21 0x7fff2594f619 <+69>: call 0x7fff25af289c ; symbol stub for: _CFSetTSD
22 0x7fff2594f61e <+74>: lea rdi, [rip + 0x6220b013] ; threadsLock
23 0x7fff2594f625 <+81>: call 0x7fff25af35bc ; symbol stub for: pthread_mutex_lock
24 0x7fff2594f62a <+86>: call 0x7fff25af361c ; symbol stub for: pthread_self
25 0x7fff2594f62f <+91>: mov rbx, rax
26 0x7fff2594f632 <+94>: cmp qword ptr [rip + 0x6220d40e], -0x1 ; performSelector:onThread:withObject:waitUntilDone:modes:.sInvalidSystem + 3
27 0x7fff2594f63a <+102>: jne 0x7fff2594fa21 ; <+1101>
28 0x7fff2594f640 <+108>: mov rdi, qword ptr [rip + 0x6220d409] ; __NSThreads.oAllThreads
29 0x7fff2594f647 <+115>: mov rsi, rbx
30 0x7fff2594f64a <+118>: mov rdx, r15
31 0x7fff2594f64d <+121>: call 0x7fff25af1f12 ; symbol stub for: CFDictionarySetValue
32 0x7fff2594f652 <+126>: mov rax, qword ptr [r15 + 0x8]
33 0x7fff2594f656 <+130>: mov byte ptr [rax + 0x37], 0xe
34 0x7fff2594f65a <+134>: lea rdi, [rip + 0x6220afd7] ; threadsLock
35 0x7fff2594f661 <+141>: call 0x7fff25af35c8 ; symbol stub for: pthread_mutex_unlock
36 0x7fff2594f666 <+146>: mov rdi, r15
37 0x7fff2594f669 <+149>: call qword ptr [rip + 0x5b02d7e9] ; (void *)0x00007fff50bbe940: objc_release
38 0x7fff2594f66f <+155>: mov rdi, r15
39 0x7fff2594f672 <+158>: call 0x7fff25af33e8 ; symbol stub for: objc_sync_enter
40 0x7fff2594f677 <+163>: call 0x7fff25af2152 ; symbol stub for: CFRunLoopGetCurrent 这里会创建这个线程的RunLoop
41 0x7fff2594f67c <+168>: mov qword ptr [rbp - 0x238], rax
42 0x7fff2594f683 <+175>: xorps xmm0, xmm0
43 0x7fff2594f686 <+178>: lea rdx, [rbp - 0x70]
44 0x7fff2594f68a <+182>: movaps xmmword ptr [rdx + 0x30], xmm0
45 0x7fff2594f68e <+186>: movaps xmmword ptr [rdx + 0x20], xmm0
46 0x7fff2594f692 <+190>: movaps xmmword ptr [rdx + 0x10], xmm0
47 0x7fff2594f696 <+194>: movaps xmmword ptr [rdx], xmm0
48 0x7fff2594f699 <+197>: mov rax, qword ptr [r15 + 0x8]
49 0x7fff2594f69d <+201>: mov rdi, qword ptr [rax + 0x38]
50 0x7fff2594f6a1 <+205>: mov rsi, qword ptr [rip + 0x621ee1d0] ; "countByEnumeratingWithState:objects:count:"
51 0x7fff2594f6a8 <+212>: lea rcx, [rbp - 0xf0]
52 0x7fff2594f6af <+219>: mov r8d, 0x10
53 0x7fff2594f6b5 <+225>: mov qword ptr [rbp - 0x208], rdi
54 0x7fff2594f6bc <+232>: call qword ptr [rip + 0x5b02d78e] ; (void *)0x00007fff50ba4400: objc_msgSend
55 0x7fff2594f6c2 <+238>: mov r12, rax
56 0x7fff2594f6c5 <+241>: test rax, rax
57 0x7fff2594f6c8 <+244>: je 0x7fff2594f957 ; <+899>
58 0x7fff2594f6ce <+250>: lea rax, [rbp - 0x70]
59 0x7fff2594f6d2 <+254>: mov rax, qword ptr [rax + 0x10]
60 0x7fff2594f6d6 <+258>: mov rax, qword ptr [rax]
61 0x7fff2594f6d9 <+261>: mov qword ptr [rbp - 0x218], rax
62 0x7fff2594f6e0 <+268>: mov rax, qword ptr [rip + 0x5b02d449] ; (void *)0x00007fff8062d6e0: kCFAllocatorSystemDefault
63 0x7fff2594f6e7 <+275>: mov rax, qword ptr [rax]
64 0x7fff2594f6ea <+278>: mov qword ptr [rbp - 0x230], rax
65 0x7fff2594f6f1 <+285>: xor ebx, ebx
66 0x7fff2594f6f3 <+287>: mov qword ptr [rbp - 0x220], r12
67 0x7fff2594f6fa <+294>: mov rax, qword ptr [rbp - 0x60]
68 0x7fff2594f6fe <+298>: mov rcx, qword ptr [rbp - 0x218]
69 0x7fff2594f705 <+305>: cmp qword ptr [rax], rcx
70 0x7fff2594f708 <+308>: je 0x7fff2594f716 ; <+322>
71 0x7fff2594f70a <+310>: mov rdi, qword ptr [rbp - 0x208]
72 0x7fff2594f711 <+317>: call 0x7fff25af3322 ; symbol stub for: objc_enumerationMutation
73 0x7fff2594f716 <+322>: mov rax, qword ptr [rbp - 0x68]
74 0x7fff2594f71a <+326>: mov r14, qword ptr [rax + 8*rbx]
75 0x7fff2594f71e <+330>: mov rax, qword ptr [r15 + 0x8]
76 0x7fff2594f722 <+334>: cmp qword ptr [rax + 0x40], 0x0
77 0x7fff2594f727 <+339>: jne 0x7fff2594f73d ; <+361>
78 0x7fff2594f729 <+341>: mov rdi, qword ptr [rip + 0x621f6fd8] ; (void *)0x00007fff87a930a0: NSMutableDictionary
79 0x7fff2594f730 <+348>: call 0x7fff25af3388 ; symbol stub for: objc_opt_new
80 0x7fff2594f735 <+353>: mov rcx, qword ptr [r15 + 0x8]
81 0x7fff2594f739 <+357>: mov qword ptr [rcx + 0x40], rax
82 0x7fff2594f73d <+361>: xorps xmm0, xmm0
83 0x7fff2594f740 <+364>: movaps xmmword ptr [rbp - 0x100], xmm0
84 0x7fff2594f747 <+371>: movaps xmmword ptr [rbp - 0x110], xmm0
85 0x7fff2594f74e <+378>: movaps xmmword ptr [rbp - 0x120], xmm0
86 0x7fff2594f755 <+385>: movaps xmmword ptr [rbp - 0x130], xmm0
87 0x7fff2594f75c <+392>: mov rdi, qword ptr [r14 + 0x20]
88 0x7fff2594f760 <+396>: mov r8d, 0x10
89 0x7fff2594f766 <+402>: mov qword ptr [rbp - 0x210], rdi
90 0x7fff2594f76d <+409>: mov rsi, qword ptr [rip + 0x621ee104] ; "countByEnumeratingWithState:objects:count:"
91 0x7fff2594f774 <+416>: lea rdx, [rbp - 0x130]
92 0x7fff2594f77b <+423>: lea rcx, [rbp - 0x1b0]
93 0x7fff2594f782 <+430>: call qword ptr [rip + 0x5b02d6c8] ; (void *)0x00007fff50ba4400: objc_msgSend
94 0x7fff2594f788 <+436>: mov qword ptr [rbp - 0x228], rbx
95 0x7fff2594f78f <+443>: test rax, rax
96 0x7fff2594f792 <+446>: je 0x7fff2594f90c ; <+824>
97 0x7fff2594f798 <+452>: mov r14, rax
98 0x7fff2594f79b <+455>: mov rax, qword ptr [rbp - 0x120]
99 0x7fff2594f7a2 <+462>: mov rax, qword ptr [rax]
100 0x7fff2594f7a5 <+465>: mov qword ptr [rbp - 0x248], rax
101 0x7fff2594f7ac <+472>: mov rax, qword ptr [rip + 0x621ee0fd] ; "objectForKey:"
102 0x7fff2594f7b3 <+479>: mov qword ptr [rbp - 0x250], rax
103 0x7fff2594f7ba <+486>: mov rax, qword ptr [rip + 0x621ee0cf] ; "setObject:forKey:"
104 0x7fff2594f7c1 <+493>: mov qword ptr [rbp - 0x240], rax
105 0x7fff2594f7c8 <+500>: xor r12d, r12d
106 0x7fff2594f7cb <+503>: mov rax, qword ptr [rbp - 0x120]
107 0x7fff2594f7d2 <+510>: mov rcx, qword ptr [rbp - 0x248]
108 0x7fff2594f7d9 <+517>: cmp qword ptr [rax], rcx
109 0x7fff2594f7dc <+520>: je 0x7fff2594f7ea ; <+534>
110 0x7fff2594f7de <+522>: mov rdi, qword ptr [rbp - 0x210]
111 0x7fff2594f7e5 <+529>: call 0x7fff25af3322 ; symbol stub for: objc_enumerationMutation
112 0x7fff2594f7ea <+534>: mov rax, qword ptr [rbp - 0x128]
113 0x7fff2594f7f1 <+541>: mov rbx, qword ptr [rax + 8*r12]
114 0x7fff2594f7f5 <+545>: mov r13, r15
115 0x7fff2594f7f8 <+548>: mov rax, qword ptr [r15 + 0x8]
116 0x7fff2594f7fc <+552>: mov rdi, qword ptr [rax + 0x40]
117 0x7fff2594f800 <+556>: mov rsi, qword ptr [rbp - 0x250]
118 0x7fff2594f807 <+563>: mov rdx, rbx
119 0x7fff2594f80a <+566>: call qword ptr [rip + 0x5b02d640] ; (void *)0x00007fff50ba4400: objc_msgSend
120 0x7fff2594f810 <+572>: mov r15, rax
121 0x7fff2594f813 <+575>: test rax, rax
122 0x7fff2594f816 <+578>: jne 0x7fff2594f8c1 ; <+749>
123 0x7fff2594f81c <+584>: xorps xmm0, xmm0
124 0x7fff2594f81f <+587>: movaps xmmword ptr [rbp - 0x1d0], xmm0
125 0x7fff2594f826 <+594>: movaps xmmword ptr [rbp - 0x1e0], xmm0
126 0x7fff2594f82d <+601>: movaps xmmword ptr [rbp - 0x1f0], xmm0
127 0x7fff2594f834 <+608>: movaps xmmword ptr [rbp - 0x200], xmm0
128 0x7fff2594f83b <+615>: mov qword ptr [rbp - 0x1c0], 0x0
129 0x7fff2594f846 <+626>: lea rax, [rip + 0x524] ; __NSThreadPerformPerform
130 0x7fff2594f84d <+633>: mov qword ptr [rbp - 0x1b8], rax
131 0x7fff2594f854 <+640>: mov edi, 0x1
132 0x7fff2594f859 <+645>: mov esi, 0x8
133 0x7fff2594f85e <+650>: call 0x7fff25af2d70 ; symbol stub for: calloc
134 0x7fff2594f863 <+655>: mov qword ptr [rbp - 0x1f8], rax
135 0x7fff2594f86a <+662>: mov rdi, qword ptr [rbp - 0x230]
136 0x7fff2594f871 <+669>: xor esi, esi
137 0x7fff2594f873 <+671>: lea rdx, [rbp - 0x200]
138 0x7fff2594f87a <+678>: call 0x7fff25af2194 ; symbol stub for: CFRunLoopSourceCreate
139 0x7fff2594f87f <+683>: mov r15, rax
140 0x7fff2594f882 <+686>: mov rax, qword ptr [rbp - 0x1f8]
141 0x7fff2594f889 <+693>: mov qword ptr [rax], r15
142 0x7fff2594f88c <+696>: mov rdi, qword ptr [rbp - 0x238]
143 0x7fff2594f893 <+703>: mov rsi, r15
144 0x7fff2594f896 <+706>: mov rdx, rbx
145 0x7fff2594f899 <+709>: call 0x7fff25af2134 ; symbol stub for: CFRunLoopAddSource
146 0x7fff2594f89e <+714>: mov rax, qword ptr [r13 + 0x8]
147 0x7fff2594f8a2 <+718>: mov rdi, qword ptr [rax + 0x40]
148 0x7fff2594f8a6 <+722>: mov rsi, qword ptr [rbp - 0x240]
149 0x7fff2594f8ad <+729>: mov rdx, r15
150 0x7fff2594f8b0 <+732>: mov rcx, rbx
151 0x7fff2594f8b3 <+735>: call qword ptr [rip + 0x5b02d597] ; (void *)0x00007fff50ba4400: objc_msgSend
152 0x7fff2594f8b9 <+741>: mov rdi, r15
153 0x7fff2594f8bc <+744>: call 0x7fff25af2122 ; symbol stub for: CFRelease
154 0x7fff2594f8c1 <+749>: mov rdi, r15
155 0x7fff2594f8c4 <+752>: call 0x7fff25af21a6 ; symbol stub for: CFRunLoopSourceSignal
156 0x7fff2594f8c9 <+757>: inc r12
157 0x7fff2594f8cc <+760>: cmp r12, r14
158 0x7fff2594f8cf <+763>: mov r15, r13
159 0x7fff2594f8d2 <+766>: jb 0x7fff2594f7cb ; <+503>
160 0x7fff2594f8d8 <+772>: mov r8d, 0x10
161 0x7fff2594f8de <+778>: mov rdi, qword ptr [rbp - 0x210]
162 0x7fff2594f8e5 <+785>: mov rsi, qword ptr [rip + 0x621edf8c] ; "countByEnumeratingWithState:objects:count:"
163 0x7fff2594f8ec <+792>: lea rdx, [rbp - 0x130]
164 0x7fff2594f8f3 <+799>: lea rcx, [rbp - 0x1b0]
165 0x7fff2594f8fa <+806>: call qword ptr [rip + 0x5b02d550] ; (void *)0x00007fff50ba4400: objc_msgSend
166 0x7fff2594f900 <+812>: mov r14, rax
167 0x7fff2594f903 <+815>: test rax, rax
168 0x7fff2594f906 <+818>: jne 0x7fff2594f7ac ; <+472>
169 0x7fff2594f90c <+824>: mov rbx, qword ptr [rbp - 0x228]
170 0x7fff2594f913 <+831>: inc rbx
171 0x7fff2594f916 <+834>: mov r12, qword ptr [rbp - 0x220]
172 0x7fff2594f91d <+841>: cmp rbx, r12
173 0x7fff2594f920 <+844>: jb 0x7fff2594f6fa ; <+294>
174 0x7fff2594f926 <+850>: mov r8d, 0x10
175 0x7fff2594f92c <+856>: mov rdi, qword ptr [rbp - 0x208]
176 0x7fff2594f933 <+863>: mov rsi, qword ptr [rip + 0x621edf3e] ; "countByEnumeratingWithState:objects:count:"
177 0x7fff2594f93a <+870>: lea rdx, [rbp - 0x70]
178 0x7fff2594f93e <+874>: lea rcx, [rbp - 0xf0]
179 0x7fff2594f945 <+881>: call qword ptr [rip + 0x5b02d505] ; (void *)0x00007fff50ba4400: objc_msgSend
180 0x7fff2594f94b <+887>: mov r12, rax
181 0x7fff2594f94e <+890>: test rax, rax
182 0x7fff2594f951 <+893>: jne 0x7fff2594f6f1 ; <+285>
183 0x7fff2594f957 <+899>: mov rdi, r15
184 0x7fff2594f95a <+902>: call 0x7fff25af33ee ; symbol stub for: objc_sync_exit
185 0x7fff2594f95f <+907>: mov edi, 0xa
186 0x7fff2594f964 <+912>: call 0x7fff25895fa4 ; NSPushAutoreleasePool
187 0x7fff2594f969 <+917>: mov r14, rax
188 0x7fff2594f96c <+920>: mov rsi, qword ptr [rip + 0x621eeb25] ; "name"
189 0x7fff2594f973 <+927>: mov rdi, r15
190 0x7fff2594f976 <+930>: call qword ptr [rip + 0x5b02d4d4] ; (void *)0x00007fff50ba4400: objc_msgSend
191 0x7fff2594f97c <+936>: test rax, rax
192 0x7fff2594f97f <+939>: je 0x7fff2594f999 ; <+965>
193 0x7fff2594f981 <+941>: mov rsi, qword ptr [rip + 0x621ee0a0] ; "UTF8String"
194 0x7fff2594f988 <+948>: mov rdi, rax
195 0x7fff2594f98b <+951>: call qword ptr [rip + 0x5b02d4bf] ; (void *)0x00007fff50ba4400: objc_msgSend
196 0x7fff2594f991 <+957>: mov rdi, rax
197 0x7fff2594f994 <+960>: call 0x7fff25af3628 ; symbol stub for: pthread_setname_np
198 0x7fff2594f999 <+965>: mov rdi, qword ptr [rip + 0x621f6df0] ; (void *)0x00007fff87b4f758: NSNotificationCenter
199 0x7fff2594f9a0 <+972>: mov rsi, qword ptr [rip + 0x621ee501] ; "defaultCenter"
200 0x7fff2594f9a7 <+979>: mov rbx, qword ptr [rip + 0x5b02d4a2] ; (void *)0x00007fff50ba4400: objc_msgSend
201 0x7fff2594f9ae <+986>: call rbx
202 0x7fff2594f9b0 <+988>: mov rsi, qword ptr [rip + 0x621ef291] ; "postNotificationName:object:userInfo:"
203 0x7fff2594f9b7 <+995>: lea rdx, [rip + 0x5b0469ca] ; @"_NSThreadDidStartNotification" 会有一个通知抛出来
204 0x7fff2594f9be <+1002>: mov rdi, rax
205 0x7fff2594f9c1 <+1005>: mov rcx, r15
206 0x7fff2594f9c4 <+1008>: xor r8d, r8d
207 0x7fff2594f9c7 <+1011>: call rbx
208 0x7fff2594f9c9 <+1013>: mov rdi, r14
209 0x7fff2594f9cc <+1016>: call 0x7fff25895fae ; NSPopAutoreleasePool
210 0x7fff2594f9d1 <+1021>: mov rax, qword ptr [r15 + 0x8]
211 0x7fff2594f9d5 <+1025>: cmp byte ptr [rax + 0x36], 0x0
212 0x7fff2594f9d9 <+1029>: jne 0x7fff2594f9eb ; <+1047>
213 0x7fff2594f9db <+1031>: mov rsi, qword ptr [rip + 0x621f0a0e] ; "main" 调用NSThread对象的main方法
214 0x7fff2594f9e2 <+1038>: mov rdi, r15
215 0x7fff2594f9e5 <+1041>: call qword ptr [rip + 0x5b02d465] ; (void *)0x00007fff50ba4400: objc_msgSend
216 0x7fff2594f9eb <+1047>: mov rdi, qword ptr [rip + 0x621f6ece] ; (void *)0x00007fff87b504c8: NSThread
217 0x7fff2594f9f2 <+1054>: mov rsi, qword ptr [rip + 0x621f0f9f] ; "exit" 调用NSThread对象的exit方法
218 0x7fff2594f9f9 <+1061>: call qword ptr [rip + 0x5b02d451] ; (void *)0x00007fff50ba4400: objc_msgSend
219 0x7fff2594f9ff <+1067>: mov rax, qword ptr [rip + 0x5b02cf9a] ; (void *)0x00007fff89cb95c0: __stack_chk_guard
220 0x7fff2594fa06 <+1074>: mov rax, qword ptr [rax]
221 0x7fff2594fa09 <+1077>: cmp rax, qword ptr [rbp - 0x30]
222 0x7fff2594fa0d <+1081>: jne 0x7fff2594fa39 ; <+1125>
223 0x7fff2594fa0f <+1083>: add rsp, 0x228
224 0x7fff2594fa16 <+1090>: pop rbx
225 0x7fff2594fa17 <+1091>: pop r12
226 0x7fff2594fa19 <+1093>: pop r13
227 0x7fff2594fa1b <+1095>: pop r14
228 0x7fff2594fa1d <+1097>: pop r15
229 0x7fff2594fa1f <+1099>: pop rbp
230 0x7fff2594fa20 <+1100>: ret
231 0x7fff2594fa21 <+1101>: lea rdi, [rip + 0x6220d020] ; __NSThreads.onceToken
232 0x7fff2594fa28 <+1108>: lea rsi, [rip + 0x5b033191] ; __block_literal_global
233 0x7fff2594fa2f <+1115>: call 0x7fff25af2f08 ; symbol stub for: dispatch_once
234 0x7fff2594fa34 <+1120>: jmp 0x7fff2594f640 ; <+108>
235 0x7fff2594fa39 <+1125>: call 0x7fff25af2c1a ; symbol stub for: __stack_chk_fail
236 0x7fff2594fa3e <+1130>: jmp 0x7fff2594fa4a ; <+1142>
237 0x7fff2594fa40 <+1132>: jmp 0x7fff2594fa4a ; <+1142>
238 0x7fff2594fa42 <+1134>: jmp 0x7fff2594fa4a ; <+1142>
239 0x7fff2594fa44 <+1136>: jmp 0x7fff2594fa4a ; <+1142>
240 0x7fff2594fa46 <+1138>: jmp 0x7fff2594fa4a ; <+1142>
241 0x7fff2594fa48 <+1140>: jmp 0x7fff2594fa4a ; <+1142>
242 0x7fff2594fa4a <+1142>: mov rbx, rax
243 0x7fff2594fa4d <+1145>: jmp 0x7fff2594fa57 ; <+1155>
244 0x7fff2594fa4f <+1147>: jmp 0x7fff2594fa51 ; <+1149>
245 0x7fff2594fa51 <+1149>: mov rbx, rax
246 0x7fff2594fa54 <+1152>: mov r15, r13
247 0x7fff2594fa57 <+1155>: mov rdi, r15
248 0x7fff2594fa5a <+1158>: call 0x7fff25af33ee ; symbol stub for: objc_sync_exit
249 0x7fff2594fa5f <+1163>: mov rdi, rbx
250 0x7fff2594fa62 <+1166>: call 0x7fff25af2b5a ; symbol stub for: _Unwind_Resume
251 0x7fff2594fa67 <+1171>: ud2

上面的汇编代码有点长,但是只需要注意三点:

1 第40行,为线程创建了对应的RunLoop;

2 第203行,会有一个通知抛出来:_NSThreadDidStartNotification

3 第213行会调用-[NSThread main]方法,main方法执行完成之后,217行会调用+[NSThread exit]方法

NSThread的start方法内部做了什么?的更多相关文章

  1. C# 多线程调用静态方法或者静态实例中的同一个方法-方法内部的变量是线程安全的

    C#  多线程调用静态方法或者静态实例中的同一个方法-方法内部的变量是线程安全的 using System;using System.Threading;using System.Threading. ...

  2. 编写高质量代码改善C#程序的157个建议——建议144:一个方法只做一件事

    建议144:一个方法只做一件事 “单一职责原则”(SRP)要求每一个类型只负责一件事情.我们将此概念扩展到方法上,就变成了:一个方法只做一件事. 回顾上一建议的代码,LocalInit和RemoteI ...

  3. UIView封装动画--iOS利用系统提供方法来做转场动画

    UIView封装动画--iOS利用系统提供方法来做转场动画 UIViewAnimationOptions option; if (isNext) { option=UIViewAnimationOpt ...

  4. UIView封装动画--iOS利用系统提供方法来做关键帧动画

    iOS利用系统提供方法来做关键帧动画 ios7以后才有用. /*关键帧动画 options:UIViewKeyframeAnimationOptions类型 */ [UIView animateKey ...

  5. UIView封装动画--iOS 利用系统提供方法来做弹性运动

    iOS 利用系统提供方法来做弹性运动 /*创建弹性动画 damping:阻尼,范围0-1,阻尼越接近于0,弹性效果越明显 velocity:弹性复位的速度 */ [UIView animateWith ...

  6. 是否可以从一个static方法内部发出对非static方法的调用

    不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方 法调用,而static方法调用时不需要创建对象,可以直接调用.也就是说,当一个static方法被调用时 ...

  7. C# 函数方法内部实现循环调用自身

    //C# 函数方法内部实现循环调用自身 void TreeViewFresh(){ Action<TreeNodeCollection, MenuItem> addNode = (Tree ...

  8. 是否可以从一个static方法内部调用非static方法?

    不可以.静态成员不能调用非静态成员. 非static方法属于对象,必须创建一个对象后,才可以在通过该对象来调用static方法.而static方法调用时不需要创建对象,通过类就可以调用该方法.也就是说 ...

  9. 220327_IDEA调试debug时step into看不了方法内部的解决办法

    220327_问题解决_IDEA Debug时stepinto无法进入方法内部的解决方法 File Settings Build,Execution,Deployment Debugger Stepp ...

  10. List中的Contains方法内部其实是用对象的equals方法做比较,所以如果比较两个类就重写类的equals方法即可;而Set是调用equals和hashCode

    public class Person { private String name; private int age; public String getName() { return name; } ...

随机推荐

  1. Amazon免费CE2基于docker部署nginx,并实现访问

    在部署之前,请确保你已经申请好了CE2免费的服务器,网上的相关教程很多,可以自由参考. 一.使用xshell+公钥连接实例 1.打开xshell,导入密钥, 选择"工具" -> ...

  2. 【Java】多线程之实现Runnable接口

    1 /** 2 * 3 */ 4 package com.raliable.chapter_0; 5 /** 6 * @author : Administrator 7 * @date :2022年4 ...

  3. Android记账本界面实现

    <!--activity_main.xml-->1 <?xml version="1.0" encoding="utf-8"?> 2 & ...

  4. 【已解决】linux环境jps命令不显示进程

    2021-09-28 10:26:42 问题描述: 输入jps后不显示进程 解决办法 1. cd /tmp/hsperfdata_root/ 2. ls 如果是空的 3. rm -rf hsperfd ...

  5. 6 HTML图片标签

    6 图片标签 在HTML中,图像由标签定义的,它可以用来加载图片到html网页中显示.网页开发过程中,有三种图片格式被广泛应用到web里,分别是 jpg.png.gif. img标签的属性: /* s ...

  6. #Every-SG#HDU 3595 GG and MM

    题目 有\(n\)个游戏,每个游戏只要能进行就必须进行, 对于每个游戏有两堆石子,每次可以将数量多的中取出小堆石子数量的整数倍, 无法操作者为负,问先手是否必胜 分析 如果单个游戏最大操作次数为奇数次 ...

  7. #后缀数组#洛谷 4051 [JSOI2007]字符加密

    题目 分析 将字符串复制一份放入末尾,将其后缀排序之后 SA数组既然表示排名为\(i\)的后缀的起始位置, 那么只要它在\([1,len]\)范围内就是合法的, 那么输出以这个位置开头长度为\(len ...

  8. 开发人员使用HANA交付业务的学习路径

    本文于2019年7月22日完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 入门 编程规范. 开发环境使用方法. 基本语法,与其它同类软件的 ...

  9. JDK14中的java tools简介

    目录 故事发生了 java tools简介 jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps ...

  10. std::thread 三:条件变量(condition_variable())

    condition_variable  .  wait   .  notify_one   .  notify_all *:notify_one:通知(唤醒)一个线程 *:notify_all:通知( ...