iOS经典面试题大全
<h2>1.INTERVIEW 共勉</h2><div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="980" data-height="236"><img src="https://upload-images.jianshu.io/upload_images/2960658-c165e9f21a2acc28.png?imageMogr2/auto-orient/strip|imageView2/2/w/980/format/webp"></div>
</div>
</div>
<blockquote>
<p>作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:638302184,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 与2800+iOS开发者一起交流学习成长!</p>
</blockquote>
<h2>2.INTERVIEW 准备</h2>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="670" data-height="327"><img src="https://upload-images.jianshu.io/upload_images/2960658-92bd71687e1d050d.png?imageMogr2/auto-orient/strip|imageView2/2/w/670/format/webp"></div>
</div>
</div>
<h2>3.iOS developers 方向</h2>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="786" data-height="245"><img src="https://upload-images.jianshu.io/upload_images/2960658-fd9a12fba11cd497.png?imageMogr2/auto-orient/strip|imageView2/2/w/786/format/webp"></div>
</div>
</div>
<h2>4.INTERVIEW QUESTION</h2>
<h4>4.1深copy和浅copy</h4>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="354" data-height="268"><img src="https://upload-images.jianshu.io/upload_images/2960658-693b2c7e1c41d82b.png?imageMogr2/auto-orient/strip|imageView2/2/w/354/format/webp"></div>
</div>
</div>
<ul>
<li>浅拷贝:<br>1.对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.<br>2.内存销毁的时候,指向这片空间的指针需要重新定义才可以使用,要不然会成为野指针<br>3.拷贝指向原来对象的指针,使原对象的引用计数加+1<br>4.相当于创建了一个指向原对象的新指针,并没有创建一个新的对象.</li>
</ul>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="363" data-height="272"><img src="https://upload-images.jianshu.io/upload_images/2960658-1aec0be3a7acfd41.png?imageMogr2/auto-orient/strip|imageView2/2/w/363/format/webp"></div>
</div>
</div>
<ul>
<li>
<p>深拷贝:<br>1.拷贝对象的具体内容,而内存地址是自主分配的<br>2.拷贝结束之后,两个对象存在的值是相同的,内存地址是不一样的<br>3.两个对象没有任何关系</p>
</li>
<li>
<p>本质区别:<br>1.深拷贝是内容拷贝,浅拷贝是指针拷贝<br>2.是否有新的内存地址<br>3.是否影响内存地址的引用计数.</p>
</li>
<li>
<p>案例一</p>
</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> NSString <span class="token operator">* str1 <span class="token operator">= <span class="token string">@"copyStr"<span class="token punctuation">;
NSMutableString <span class="token operator">*str2 <span class="token operator">= <span class="token punctuation"><span class="token punctuation">;
NSMutableString <span class="token operator">*str3 <span class="token operator">= <span class="token punctuation"><span class="token punctuation">;
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"str1:%p--%@"<span class="token punctuation">,str1<span class="token punctuation">,str1<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"str1:%p--%@"<span class="token punctuation">,str2<span class="token punctuation">,str2<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"str1:%p--%@"<span class="token punctuation">,str3<span class="token punctuation">,str3<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-css"><code class="language-css">2018-04-14 14<span class="token punctuation">:50<span class="token punctuation">:54.117652+0800 MutyCopy-Copy <span class="token property">str1<span class="token punctuation">:0x109a48068--copyStr
2018-04-14 14<span class="token punctuation">:50<span class="token punctuation">:54.117885+0800 MutyCopy-Copy <span class="token property">str1<span class="token punctuation">:0x109a48068--copyStr
2018-04-14 14<span class="token punctuation">:50<span class="token punctuation">:54.118010+0800 MutyCopy-Copy <span class="token property">str1<span class="token punctuation">:0x600000259a40--copyStr
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>1.str1,str2地址相同,而Str3地址不同<br>2.NSString的copy是浅拷贝,copy返回的对象是不可变对象<br>3.mutablecopy是深拷贝</p>
<p>*案例二:</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> NSMutableString <span class="token operator">* str1 <span class="token operator">= <span class="token punctuation"><span class="token punctuation">;
NSMutableString <span class="token operator">* str2 <span class="token operator">= <span class="token punctuation"><span class="token punctuation">;
NSMutableString <span class="token operator">* str3 <span class="token operator">= <span class="token punctuation"><span class="token punctuation">;
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"str:%p-----%@"<span class="token punctuation">,str1<span class="token punctuation">,str1<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"str:%p-----%@"<span class="token punctuation">,str2<span class="token punctuation">,str2<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"str:%p-----%@"<span class="token punctuation">,str3<span class="token punctuation">,str3<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-css"><code class="language-css">2018-04-14 15<span class="token punctuation">:04<span class="token punctuation">:50.092820+0800 MutyCopy-Copy <span class="token property">str<span class="token punctuation">:0x60000025b210-----mutableStr
2018-04-14 15<span class="token punctuation">:04<span class="token punctuation">:50.093059+0800 MutyCopy-Copy <span class="token property">str<span class="token punctuation">:0x60000022ca40-----mutableStr
2018-04-14 15<span class="token punctuation">:04<span class="token punctuation">:50.093217+0800 MutyCopy-Copy <span class="token property">str<span class="token punctuation">:0x60000025b540-----mutableStr
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>1.str1,str2,str3地址都不同<br>2.NSMutableString对象copy与mutableCopy都是深拷贝<br>3.copy返回的对象是不可变对象</p>
<h4>4.2 iOS程序的启动过程</h4>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="715" data-height="401"><img src="https://upload-images.jianshu.io/upload_images/2960658-aaaecbb2fbd4b377.png?imageMogr2/auto-orient/strip|imageView2/2/w/715/format/webp"></div>
</div>
</div>
<ul>
<li>首先找到程序入口,执行main函数</li>
<li>main -->> UIApplicationMain</li>
<li>创建UIApplication对象</li>
<li>创建UIApplication的代理对象,给UIApplication对象代理属性赋值</li>
<li>开启主运行循环,作用接收事件,让程序一直运行</li>
<li>加载info.plist,判断有没有指定main.storyboard,如果指定就去加载.</li>
</ul>
<h4>4.3 loadView</h4>
<ul>
<li>什么时候被调用?<br>每次访问VC的view而且view为nil,loadView方法被调用</li>
<li>作用<br>loadView方法是用来负责创建VC的view.</li>
<li>默认实现是怎样的?<br>默认实现即<br>1.它会先去查找与UIViewController相关联的xib文件,通过加载xib文件来创建VC的view.<br>2.如果在初始化VC指定了xib文件名,就会根据传入的xib文件名加载对应的xib文件.如果没有明显xib文件名,就会加载跟自己同名的xib文件.<br>3.如果没有找到关联的xib文件,就会创建一个空白的UIView,然后赋值给VC的view属性</li>
</ul>
<h4>4.4 单例模式</h4>
<h4>4.5 多线程</h4>
<ul>
<li>
<p>进程<br>1.进程是指系统中正在运行的一个应用程序<br>2.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内.</p>
</li>
<li>
<p>线程<br>1.1个进程要想执行任务,必须得有线程,每1个进程至少要有1条线程<br>2.线程是进程的基本执行单元<br>3.一个进程的素有任务都在线程中执行</p>
</li>
<li>
<p>多线程<br>1.1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务<br>2.进程--工厂,线程--工厂工人<br>3.多线程可以提高程序的执行效率</p>
</li>
</ul>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="734" data-height="420"><img src="https://upload-images.jianshu.io/upload_images/2960658-e040023dc2a3958b.png?imageMogr2/auto-orient/strip|imageView2/2/w/734/format/webp"></div>
</div>
</div>
<p>比如,我们同时开启2条线程下载文件A,文件B.</p>
<ul>
<li>多线程的原理<br>1.同一时间,CPU只能处理1条线程,只有1条线程在工作<br>2.多线程并发执行,是CPU快速地在多条线程之间调度切换</li>
</ul>
<blockquote>
<p>注意:如果线程非常非常多,会发生什么情况?<br>cpu会在多个多线程之间进行调度,消耗大量的CPU资源.这样的话,每条线程被调度执行的频次会降低,线程执行效率降低.</p>
</blockquote>
<ul>
<li>
<p>多线程的优缺点<br>1.优点:<br>1.1.能适当的提高程序的执行效率<br>1.2.能适当调高资源利用率<br>2.缺点:<br>2.1.开启线程需要占用一定的内存空间,如果开启大量的线程,会占用大量的内存空间,降低程序的性能<br>2.2线程越多,CPU在调度线程上的开销就越大.</p>
</li>
<li>
<p>多线程应用<br>1.什么是主线程?<br>一个iOS程序运行后,默认会开启1条线程 ,称为主线程<br>2.主线程的主要作用?<br>2.1.显示/刷新UI界面<br>2.2.处理UI事件<br>3.主线程使用注意?<br>3.1.别将比较耗时的操作放到主线程中<br>3.2.耗时操作会卡住主线程,严重影响UI的流畅度<br>4.多线程实现技术方案?<br>pthread,NSThread,GCD,NSOperation四中方案.</p>
</li>
</ul>
<h4>4.6 NSThread</h4>
<ul>
<li>创建,启动线程</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec">NSThread <span class="token operator">*thread <span class="token operator">= <span class="token punctuation">[<span class="token punctuation"> initWithTarget<span class="token punctuation">:<span class="token keyword">self selector<span class="token punctuation">:<span class="token keyword">@selector<span class="token punctuation">(threadFun<span class="token punctuation">) object<span class="token punctuation">:nil<span class="token punctuation">]<span class="token punctuation">;
<span class="token punctuation"><span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>线程一启动,就会告诉CPU准别就绪,可以随时接受CPU调度.CPU调度当前线程之后,就会在线程thread中执行self的run方法</p>
<ul>
<li>主线程用法</li>
</ul>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="906" data-height="511"><img src="https://upload-images.jianshu.io/upload_images/2960658-588d4465fe147299.png?imageMogr2/auto-orient/strip|imageView2/2/w/906/format/webp"></div>
</div>
</div>
<ul>
<li>其他方式创建线程<br>创建线程后自动启动线程</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token punctuation"><span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>隐式创建并启动线程</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token punctuation">[<span class="token keyword">self performSelectorInBackground<span class="token punctuation">:<span class="token keyword">@selector<span class="token punctuation">(run<span class="token punctuation">) withObject<span class="token punctuation">:nil<span class="token punctuation">]<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>
<p>线程状态</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="809" data-height="332"><img src="https://upload-images.jianshu.io/upload_images/2960658-1d408746782bd6d9.png?imageMogr2/auto-orient/strip|imageView2/2/w/809/format/webp"></div>
</div>
</div>
</li>
</ul>
<p>1.启动线程,start.就绪状态-->>运行状态.当新厂任务执行完毕,自动进入死亡状态<br>2.阻塞(暂停)线程,进入阻塞状态</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token operator">+ <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)sleepUntilDate<span class="token punctuation">:<span class="token punctuation">(NSDate <span class="token operator">*<span class="token punctuation">)date<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></code></pre>
</div>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token operator">+ <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)sleepForTimeInterval<span class="token punctuation">:<span class="token punctuation">(NSTimeInterval<span class="token punctuation">)ti<span class="token punctuation">;
</span></span></span></span></span></span></span></span></code></pre>
</div>
<p>3.强制停止线程<br>进入死亡状态</p>
<blockquote>
<p>注意:一旦线程停止了,就不能再次开启任务.</p>
</blockquote>
<ul>
<li>
<p>多线程的安全隐患<br>1.资源共享<br>一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源.当多线程访问同一块资源时,很容易引发数据错乱和数据安全问题.<br>2.如图,</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="574" data-height="319"><img src="https://upload-images.jianshu.io/upload_images/2960658-c807e2c3f114afbe.png?imageMogr2/auto-orient/strip|imageView2/2/w/574/format/webp"></div>
</div>
</div>
</li>
</ul>
<p>如果,多个线程访问同一块资源的话,会造成数据错乱的.<br>我们应该怎么解决呢?</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="624" data-height="383"><img src="https://upload-images.jianshu.io/upload_images/2960658-8316aaa6ef2033da.png?imageMogr2/auto-orient/strip|imageView2/2/w/624/format/webp"></div>
</div>
<div class="image-caption">image</div>
</div>
<p>3.如图,<br>线程A和线程B同时访问资源变量Integer,<br>为了防止抢夺资源,<br>线程A在读取资源变量Integer之前先加一把锁,<br>然后读取Integer的数据并在线程A中完成数据操作(17+1=18),<br>然后把数据写入Integer中,<br>最后开锁Unlock.在线程A对Integer操作的过程中,<br>线程B是无权访问Integer的,<br>只有线程A_Unlock后,线程B才可以访问资源变量Integer.<br>4.互斥锁使用格式<br>@synchronized(self){//需要锁定的代码}</p>
<blockquote>
<p>注意: 锁定1分代码只用1把锁,用多把锁是无效的</p>
</blockquote>
<p>5.互斥锁的优缺点<br>互斥锁的使用前提:多条线程抢夺同一块资源<br>优点:能有效防止因多线程抢夺资源造成的数据安全问题<br>缺点:需要消耗大量的CPU</p>
<p>6.nonatomic和atomic<br>atomic:<br>原子属性,为setter方法加锁(默认就是atomic)<br>线程安全,需要消耗大量的资源<br>nonatomic:<br>非原子属性,不会为setter方法加锁<br>非线程安全,适合内存小的移动设备</p>
<h4>4.7 GCD</h4>
<ul>
<li>什么是GCD?<br>全程Grand Central Dispatch,中枢调度器<br>纯C语言,提供了非常多强大的函数</li>
<li>GCD的优势<br>1.GCD是苹果公司为多核的并行运算提出的解决方案<br>2.GCD会自动利用更多的CPU内核<br>3.GCD自动管理线程的生命周期(创建线程,调度任务,销毁线程)</li>
<li>GCD有2个核心概念<br>1.任务:执行什么操作<br>2.队列;用来存放任务</li>
<li>任务和队列</li>
</ul>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="777" data-height="221"><img src="https://upload-images.jianshu.io/upload_images/2960658-044d18f320467d52.png?imageMogr2/auto-orient/strip|imageView2/2/w/777/format/webp"></div>
</div>
</div>
<p>1.执行任务<br>GCD中有2个用来执行任务的函数<br>1.1用同步的方式执行任务</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"><span class="token function">dispatch_sync<span class="token punctuation">(dispatch_queue_t queue<span class="token punctuation">, dispatch_block_t block<span class="token punctuation">)<span class="token punctuation">;
queue:队列
block:任务
</span></span></span></span></span></code></pre>
</div>
<p>1.2用异步的方式执行任务</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"><span class="token function">dispatch_async<span class="token punctuation">(dispatch_queue_t queue<span class="token punctuation">, dispatch_block_t block<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></code></pre>
</div>
<p>1.3同步和异步的区别<br>同步:只能在当前线程中执行任务,不具备开启新线程的能力<br>异步:可以再新的线程中执行任务,具备开启新线程的能力</p>
<ul>
<li>队列的类型<br>GCD的队列可以分为2大类型<br>并发队列:可以让多个任务并发执行(并发功能只能在异步函数下才有效)<br>串行队列:让任务一个接着一个地执行</li>
<li>容易混淆的术语<br>有4个术语比较容易混淆:<br>同步,异步,并发,串行</li>
</ul>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="923" data-height="274"><img src="https://upload-images.jianshu.io/upload_images/2960658-4367f83a2a98c71d.png?imageMogr2/auto-orient/strip|imageView2/2/w/923/format/webp"></div>
</div>
</div>
<blockquote>
<p>注意: 同步函数 + 主队列 == 死锁</p>
</blockquote>
<ul>
<li>并发队列<br>GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建<br>使用dispatch_get_global_queue函数获得全局的并发队列</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp">dispatch_queue_t <span class="token function">dispatch_get_global_queue<span class="token punctuation">(
dispatch_queue_priority_t priority<span class="token punctuation">,队列的优先级
<span class="token keyword">unsigned <span class="token keyword">long flags<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></code></pre>
</div>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp">全局并发队列
dispatch_queue_t queue <span class="token operator">=
<span class="token function">dispatch_get_global_queue<span class="token punctuation">(DISPATCH_QUEUE_PRIORITY_DEFAULT<span class="token punctuation">, <span class="token number">0<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></code></pre>
</div>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="811" data-height="301"><img src="https://upload-images.jianshu.io/upload_images/2960658-63dbc07055438b8e.png?imageMogr2/auto-orient/strip|imageView2/2/w/811/format/webp"></div>
</div>
</div>
<ul>
<li>串行队列<br>GCD中获得串行的2中途径<br>1.使用dispatch_queue_create函数创建串行队列</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp">dispatch_queue_t <span class="token operator">=
<span class="token function">dispatch_queue_create<span class="token punctuation">(<span class="token keyword">const <span class="token keyword">char<span class="token operator">*label<span class="token punctuation">,队列名称
dispatch_queue_attr_t attr<span class="token punctuation">)<span class="token punctuation">;队列属性,一般用<span class="token constant">NULL即可
</span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>2.使用主队列<br>放在主队列中的任务,都会放到主线程中执行<br>使用dispatch_get_main_queue()获得主队列</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp">dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></code></pre>
</div>
<ul>
<li>从子线程回到主线程</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token function">dispatch_async<span class="token punctuation">(
<span class="token function">dispatch_get_global_queue<span class="token punctuation">(DISPATCH_QUEUE_PRIORITY_DEFAULT<span class="token punctuation">, <span class="token number">0<span class="token punctuation">)<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
执行耗时的异步操作<span class="token punctuation">.<span class="token punctuation">.<span class="token punctuation">.
<span class="token function">dispatch_async<span class="token punctuation">(<span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
回到主线程,执行UI刷新操作
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>延时执行</li>
</ul>
<p>设定好延迟的时间后,它会先执行后边的代码,2秒后再调用self的run方法(并且不会卡主线程,在主线程调最后会回到主线程,在子线程调最后会回到子线程)</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec">withObject<span class="token punctuation">:参数
afterDelay<span class="token punctuation">:延迟的时间
<span class="token punctuation">[<span class="token keyword">self performSelector<span class="token punctuation">:<span class="token keyword">@selector<span class="token punctuation">(run<span class="token punctuation">) withObject<span class="token punctuation">:nil afterDelay<span class="token punctuation">:<span class="token number">2.0<span class="token punctuation">]<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>使用GCD函数(2秒后自动开启新线程 执行block中的代码,不会卡主当前的线程,在主/子线程调用都可以使用)</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec">DISPATCH_TIME_NOW<span class="token punctuation">:现在开始的意
<span class="token number">2.0 <span class="token operator">* NSEC_PER_SEC<span class="token punctuation">:设置的秒数<span class="token punctuation">(直接更改数字即可<span class="token punctuation">)
<span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">:主队列的意思
<span class="token function">dispatch_after<span class="token punctuation">(<span class="token function">dispatch_time<span class="token punctuation">(DISPATCH_TIME_NOW<span class="token punctuation">, <span class="token punctuation">(int64_t<span class="token punctuation">)<span class="token punctuation">(<span class="token number">2.0 <span class="token operator">* NSEC_PER_SEC<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">, <span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token number">2秒后执行这里的代码<span class="token punctuation">.<span class="token punctuation">.<span class="token punctuation">. 在哪个线程执行,跟队列类型有关
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>3.会卡住主线程</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-json"><code class="language-json"><span class="token punctuation">
</span></span></span></span></code></pre>
</div>
<ul>
<li>只执行一次<br>使用dispatch_once函数能保证某段代码在程序运行过程中只被执行1次<br>在设计模式中,单例模式也会用到</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token keyword">static dispatch_once_t onceToken<span class="token punctuation">;
<span class="token function">dispatch_once<span class="token punctuation">(<span class="token operator">&onceToken<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
程序运行过程中<span class="token punctuation">,永远只执行<span class="token number">1次的代码<span class="token punctuation">(这里面默认是线程安全的<span class="token punctuation">)
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>队列组<br>需求:1.分别异步执行2个耗时的操作,其次,等2个异步操作都执行完毕后,再回到主线程执行操作</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-csharp"><code class="language-csharp">dispatch_group_t <span class="token keyword">group <span class="token operator">=<span class="token function">dispatch_group_create<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">dispatch_group_async<span class="token punctuation">(<span class="token keyword">group<span class="token punctuation">, <span class="token function">dispatch_get_global_queue<span class="token punctuation">(DISPATCH_QUEUE_PRIORITY_DEFAULT<span class="token punctuation">, <span class="token number">0<span class="token punctuation">)<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
执行<span class="token number">1个耗时的异步操作
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">dispatch_group_async<span class="token punctuation">(<span class="token keyword">group<span class="token punctuation">, <span class="token function">dispatch_get_global_queue<span class="token punctuation">(DISPATCH_QUEUE_PRIORITY_DEFAULT<span class="token punctuation">, <span class="token number">0<span class="token punctuation">)<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
执行<span class="token number">1个耗时的异步操作
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">dispatch_group_notify<span class="token punctuation">(<span class="token keyword">group<span class="token punctuation">, <span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
等前面的异步操作都执行完毕后,回到主线程<span class="token punctuation">.<span class="token punctuation">.<span class="token punctuation">.
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>
<p>GCD的创建和释放<br>在iOS6.0之前,在GCD中每当使用带creat单词的函数创建对象之后,都应该对其进行一次release操作.<br>在iOS6.0之后,GCD被纳入到了ARC的内存管理机制中,在使用GCD的时候我们就像对待普通OC对象一样对待GCD,因此不再需要我们调用release方法.</p>
</li>
<li>
<p>GCD 的基本使用</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="548" data-height="311"><img src="https://upload-images.jianshu.io/upload_images/2960658-88ceb6b8ccf086b5.png?imageMogr2/auto-orient/strip|imageView2/2/w/548/format/webp"></div>
</div>
<div class="image-caption">image</div>
</div>
<p>1.异步函数+并发队列</p>
</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token number">1.创建队列<span class="token punctuation">(并发队列<span class="token punctuation">)
dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_queue_create<span class="token punctuation">(<span class="token string">"com.baidu.www"<span class="token punctuation">, DISPATCH_QUEUE_CONCURRENT<span class="token punctuation">)<span class="token punctuation">;
异步函数
<span class="token function">dispatch_async<span class="token punctuation">(queue<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"1---%@"<span class="token punctuation">,<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>2.异步函数+串行队列</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> <span class="token number">1.创建队列<span class="token punctuation">(串行队列<span class="token punctuation">)
dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_queue_create<span class="token punctuation">(<span class="token string">"com.baidu.www"<span class="token punctuation">, DISPATCH_QUEUE_SERIAL<span class="token punctuation">)<span class="token punctuation">;
异步函数
<span class="token function">dispatch_async<span class="token punctuation">(queue<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"1---%@"<span class="token punctuation">,<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>3.同步函数+串行队列</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> <span class="token number">1.创建队列<span class="token punctuation">(串行队列<span class="token punctuation">)
dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_queue_create<span class="token punctuation">(<span class="token string">"com.baidu.www"<span class="token punctuation">, DISPATCH_QUEUE_SERIAL<span class="token punctuation">)<span class="token punctuation">;
同步函数
<span class="token function">dispatch_sync<span class="token punctuation">(queue<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"1---%@"<span class="token punctuation">,<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>4.同步函数+并发队列</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> <span class="token comment">//获得全局并发队列
dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_get_global_queue<span class="token punctuation">(DISPATCH_QUEUE_PRIORITY_DEFAULT<span class="token punctuation">, <span class="token number">0<span class="token punctuation">)<span class="token punctuation">;
<span class="token comment">// 同步函数
<span class="token function">dispatch_sync<span class="token punctuation">(queue<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"1---%@"<span class="token punctuation">,<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>5.异步函数+主队列</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token number">1.获得主队列
dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
异步函数
<span class="token function">dispatch_async<span class="token punctuation">(queue<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"1---%@"<span class="token punctuation">,<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>6.同步函数+主队列</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> <span class="token number">1.获得主队列
dispatch_queue_t queue <span class="token operator">= <span class="token function">dispatch_get_main_queue<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
<span class="token function">dispatch_sync<span class="token punctuation">(queue<span class="token punctuation">, <span class="token operator">^<span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(<span class="token string">@"1---%@"<span class="token punctuation">,<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<h4>4.8 NSOperation</h4>
<ul>
<li>NSOperation作用?<br>配合使用NSOperation 和NSOperationQueue也能实现多线程编程</li>
<li>NSOperation 和NSOperationoQueue实现多线程的具体步骤</li>
</ul>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="449" data-height="243"><img src="https://upload-images.jianshu.io/upload_images/2960658-01752677cdcdf6d8.png?imageMogr2/auto-orient/strip|imageView2/2/w/449/format/webp"></div>
</div>
</div>
<ul>
<li>
<p>NSOperation的子类<br>NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类<br>子类的方式有3中:<br>1.NSInvocationOperation<br>2.NSBlockOperation<br>3.自定义子类继承NSOperation,实现内部响应的方法</p>
</li>
<li>
<p>NSInvocationOperation<br>1.创建对象</p>
</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-css"><code class="language-css">- <span class="token punctuation">(id<span class="token punctuation">)<span class="token property">initWithTarget<span class="token punctuation">:<span class="token punctuation">(id<span class="token punctuation">)target <span class="token property">selector<span class="token punctuation">:<span class="token punctuation">(SEL<span class="token punctuation">)sel <span class="token property">object<span class="token punctuation">:<span class="token punctuation">(id<span class="token punctuation">)arg<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>2.调用start方法开始执行操作</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"><span class="token operator">- <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)start<span class="token punctuation">;
</span></span></span></span></span></code></pre>
</div>
<p>一旦执行操作,就会调用target的sel方法</p>
<blockquote>
<p>默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作;只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作</p>
</blockquote>
<ul>
<li>NSBlockOperation<br>1.创建NSBlockOperation对象</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token operator">+ <span class="token punctuation">(id<span class="token punctuation">)blockOperationWithBlock<span class="token punctuation">:<span class="token punctuation">(<span class="token keyword">void <span class="token punctuation">(<span class="token operator">^<span class="token punctuation">)<span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)<span class="token punctuation">)block<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>通过addExecutionBlock:方法添加更多的操作</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"><span class="token operator">- <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)addExecutionBlock<span class="token operator">:<span class="token punctuation">(<span class="token keyword">void <span class="token punctuation">(<span class="token operator">^<span class="token punctuation">)<span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)<span class="token punctuation">)block<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<blockquote>
<p>只要NSBlockOperation封装的操作数 > 1,就会异步执行操作</p>
</blockquote>
<ul>
<li>NSOperationQueue作用<br>如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperationQueue中的操作</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token operator">- <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)addOperation<span class="token punctuation">:<span class="token punctuation">(NSOperation <span class="token operator">*<span class="token punctuation">)operation<span class="token punctuation">;
<span class="token operator">- <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)addOperationWithBlock<span class="token punctuation">:<span class="token punctuation">(<span class="token keyword">void <span class="token punctuation">(<span class="token operator">^<span class="token punctuation">)<span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)<span class="token punctuation">)block<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>最大并发数<br>同时执行的任务数<br>最大并发数相关的方法</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token operator">-<span class="token punctuation">(NSInteger<span class="token punctuation">)maxConcurrentOperationCount<span class="token punctuation">;
<span class="token operator">- <span class="token punctuation">(<span class="token keyword">void<span class="token punctuation">)setMaxConcurrentOperationCount<span class="token punctuation">:<span class="token punctuation">(NSInteger<span class="token punctuation">)cnt<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>自定义NSOperation<br>重写-(void)main方法,在里面实现想执行的任务<br>重写-(void)main方法的注意点:自动创建自动释放池,如果是异步操作,无法访问主线程的自动释放池</li>
</ul>
<h4>4.9 RunLoop</h4>
<ul>
<li>如果没有RunLoop,程序输出后就退出了</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"><span class="token keyword">int <span class="token function">main<span class="token punctuation">(<span class="token keyword">int argc<span class="token punctuation">, <span class="token keyword">char <span class="token operator">* argv<span class="token punctuation">[<span class="token punctuation">]<span class="token punctuation">) <span class="token punctuation">{
<span class="token function">NSLog<span class="token punctuation">(@<span class="token string">"main"<span class="token punctuation">)<span class="token punctuation">;
<span class="token keyword">return <span class="token number">0<span class="token punctuation">;
<span class="token punctuation">}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>如果有了RunLoop,由于main函数里面启动了RunLoop,所以程序并不会马上退出,保持持续运行状态</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token keyword">int <span class="token function">main<span class="token punctuation">(<span class="token keyword">int argc<span class="token punctuation">, <span class="token keyword">char <span class="token operator">* argv<span class="token punctuation">[<span class="token punctuation">]<span class="token punctuation">) <span class="token punctuation">{
BOOL run <span class="token operator">= YES<span class="token punctuation">;
<span class="token keyword">do<span class="token punctuation">{
<span class="token comment">//执行各种任务,处理各种事件
<span class="token punctuation">}<span class="token keyword">while<span class="token punctuation">(run<span class="token punctuation">)<span class="token punctuation">;
<span class="token keyword">return <span class="token number">0<span class="token punctuation">;
<span class="token punctuation">}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>main函数中的RunLoop,UIApplicationMaiin函数内部就启动了一个RunLoop,所以UIApplicationMain函数一直没有返回,保持了程序的持续运行,这个默认启动的RunLoop跟主线程相关联</li>
</ul>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token keyword">int <span class="token function">main<span class="token punctuation">(<span class="token keyword">int argc<span class="token punctuation">, <span class="token keyword">char <span class="token operator">* argv<span class="token punctuation">[<span class="token punctuation">]<span class="token punctuation">) <span class="token punctuation">{
<span class="token operator">@autoreleasepool <span class="token punctuation">{
<span class="token keyword">return <span class="token function">UIApplicationMain<span class="token punctuation">(argc<span class="token punctuation">, argv<span class="token punctuation">, nil<span class="token punctuation">, <span class="token function">NSStringFromClass<span class="token punctuation">(<span class="token punctuation"><span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}
<span class="token punctuation">}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<ul>
<li>
<p>RunLoop与线程<br>1.每条线程都有唯一的与之对应的RunLoop对象<br>2.主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建<br>3.RunLoop在第一次获取时创建,在线程结束时销毁</p>
</li>
<li>
<p>获得RunLoop对象</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="1108" data-height="163"><img src="https://upload-images.jianshu.io/upload_images/2960658-deddefe2da09d8d0.png?imageMogr2/auto-orient/strip|imageView2/2/w/1108/format/webp"></div>
</div>
</div>
</li>
<li>
<p>RunLoop相关类</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="384" data-height="302"><img src="https://upload-images.jianshu.io/upload_images/2960658-c263ff1ca2e35c2b.png?imageMogr2/auto-orient/strip|imageView2/2/w/384/format/webp"></div>
</div>
</div>
</li>
</ul>
<p>Core Foundation中关于RunLoop的5个类:<br>CFRunLoopRef:它自己,也就代表一个RunLoop对象<br>CFRunLoopModeRef:RunLoop的运行模式<br>CFRunLoopSourceRef:事件源<br>CFRunLoopTimerRef:时间的触发器<br>CFRunLoopbaserverRef:观察者 监听CFRunLoopRef的状态</p>
<ul>
<li>
<p>CFRunLoopModeRef<br>系统默认注册了5个Mode模式:<br>kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行<br>UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响<br>UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用<br>GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到<br>kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode</p>
</li>
<li>
<p>RunLoop处理逻辑</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="622" data-height="436"><img src="https://upload-images.jianshu.io/upload_images/2960658-7e90e1edf06c8553.png?imageMogr2/auto-orient/strip|imageView2/2/w/622/format/webp"></div>
</div>
<div class="image-caption">image</div>
</div>
</li>
</ul>
<p>1.通知观察者,即将进入Loop<br>2.通知观察者,将要处理定时器<br>3.通知观察者,将要处理非基于端口的源<br>4.处理非基于端口的源<br>5.如果有基于端口的源准备好并处于等待状态,立即启动,跳到第9步<br>6.通知观察者,线程即将休眠<br>7.休眠,等待唤醒<br>8.通知观察者,线程刚被唤醒<br>9.处理唤醒时收到的消息,之后跳到第2步<br>10.通知观察者,即将推出Loop</p>
<ul>
<li>
<p>RunLoop应用</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="623" data-height="77"><img src="https://upload-images.jianshu.io/upload_images/2960658-846371804407d846.png?imageMogr2/auto-orient/strip|imageView2/2/w/623/format/webp"></div>
</div>
</div>
</li>
<li>
<p>RunLoop面试题<br>1.什么是RunLoop?<br>字面意思运行循环<br>其实它内部就是do-while循环,这个循环内部不断处理各种任务(比如Source,Timer,Observer);<br>一个线程对应一个RunLoop,主线程的RunLoop默认启动,子线程的RunLoop手动启动;<br>RunLoop只能选择一个Mode启动,如果当前Mode中没有任何Source,Timer,那么就直接退出RunLoop.</p>
</li>
</ul>
<h4>4.10 HTTP通信过程-请求/响应</h4>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="640" data-height="283"><img src="https://upload-images.jianshu.io/upload_images/2960658-2541e2cd2c38a2b7.png?imageMogr2/auto-orient/strip|imageView2/2/w/640/format/webp"></div>
</div>
</div>
<p>HTTP协议规定:1个完整的由客户端发给服务器的HTTP请求中包含以下内容</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="1001" data-height="367"><img src="https://upload-images.jianshu.io/upload_images/2960658-e00009d094d85eb0.png?imageMogr2/auto-orient/strip|imageView2/2/w/1001/format/webp"></div>
</div>
</div>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="835" data-height="347"><img src="https://upload-images.jianshu.io/upload_images/2960658-6a71951e902ece50.png?imageMogr2/auto-orient/strip|imageView2/2/w/835/format/webp"></div>
</div>
</div>
<p>文章来源于网络,如有侵权,请联系小编删除。</p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="750" data-height="280"><img src="https://upload-images.jianshu.io/upload_images/12311242-a79aed2c9515eef1.jpg?imageMogr2/auto-orient/strip|imageView2/2/w/750/format/webp"></div>
</div>
</div><br><br>
来源:https://www.cnblogs.com/iOSer1122/p/12109968.html
頁:
[1]