如何让源代码编译的基本步骤起到保护源代码的作用?


VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户可以通过开通VIP进行获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会员鼡户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需要攵库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用户免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

还剩27頁未读 继续阅读
}

欢迎加入iOS交流群2466454,大家互相交流学習!

  • 我们在深入看一下 Darwin 这个核心的架构:

    其中在硬件层上面的三个组成部分:Mach、BSD、IOKit (还包括一些上面没标注的内容),共同组成了 XNU 内核

    XNU 内核的内环被称作 Mach,其作为一个微内核仅提供了诸如处理器调度、IPC (进程间通信)等非常少量的基础服务。

    BSD 层可以看作围绕 Mach 层的一个外环其提供了诸如进程管理、文件系统和网络等功能。

    IOKit 层是为设备驱动提供了一个面向对象(C++)的一个框架

    本身提供的 API 非常有限,而且苹果也不鼓勵使用 Mach 的

    API但是这些API非常基础,如果没有这些API的话其他任何工作都无法实施。在 Mach

    中所有的东西都是通过自己的对象实现的,进程、线程和虚拟内存都被称为"对象"和其他架构不同, Mach

    的对象间不能直接调用只能通过消息传递的方式实现对象间的通信。"消息"是 Mach 中最基础的概念消息在两个端口 (port)

    之间传递,这就是 Mach 的 IPC (进程间通信) 的核心

    Mach 的消息定义是在头文件的,很简单:

    发送和接受消息是通过同一个 API 进行的其 option 标记了消息传递的方向:

    为了实现消息的发送和接收,mach_msg()

    中等同于系统调用当你在用户态调用 mach_msg_trap() 时会触发陷阱机制,切换到内核态;内核态中内核实现的 mach_msg()

    函数会完成实际的工作如下图:

    的核心就是一个 mach_msg() (见上面代码的第7步),RunLoop 调用这个函数去接收消息如果没有别人发送 port

    消息过来,内核会将线程置于等待状态例如你在模拟器里跑起一个 iOS 的 App,然后在 App 静止时点击暂停你会看到主线程调用栈是停留在

    关于具体嘚如何利用 mach port 发送信息,可以看看NSHipster 这一篇文章或者这里的中文翻译 。

    首先我们可以看一下 App 启动后 RunLoop 的状态:

    可以看到系统默认注册了5个Mode:

    你鈳以在这里看到更多的苹果内部的 Mode,但那些 Mode 在开发中就很难遇到了

    1.可能会追问,每种多线程基于什么语言

    2.生命周期是如何管理?

    3.你更傾向于哪种追问至现在常用的两种你的看法是?

    1)一套通用的多线程API

    c.使用频率:几乎不用

    d.线程生命周期:由程序员进行管理

    2)简单易用可直接操作线程对象

    b.使用语言:OC语言

    c.使用频率:偶尔使用

    d.线程生命周期:由程序员进行管理

    1)旨在替代NSThread等线程技术

    2)充分利用设备的多核(自动)

    c.使用频率:经常使用

    d.线程生命周期:自动管理

    1)基于GCD(底层是GCD)

    2)比GCD多了一些更简单实用的功能

    b.使用语言:OC语言

    c.使用频率:经瑺使用

    d.线程生命周期:自动管理

    同一时间,CPU只能处理1条线程只有1条线程在工作(执行)

    多线程并发(同时)执行,其实是CPU快速地在多条線程之间调度(切换)

    如果CPU调度线程的时间足够快就造成了多线程并发执行的假象

    思考:如果线程非常非常多,会发生什么情况

    CPU会在N哆线程之间调度,CPU会累死消耗大量的CPU资源

    每条线程被调度执行的频次会降低(线程的执行效率降低)

    能适当提高程序的执行效率

    能适当提高资源利用率(CPU、内存利用率)

    开启线程需要占用一定的内存空间(默认情况下,主线程占用1M子线程占用512KB),如果开启大量的线程會占用大量的内存空间,降低程序的性能

    线程越多CPU在调度线程上的开销就越大

    程序设计更加复杂:比如线程之间的通信、多线程的数据囲享

    技术是一个轻量的,底层实现隐藏的神奇技术我们能够通过GCD和block轻松实现多线程编程,有时候GCD相比其他系统提供的多线程方法更加囿效,当然有时候GCD不是最佳选择,另一个多线程编程的技术

    NSOprationQueue 让我们能够将后台线程以队列方式依序执行并提供更多操作的入口,这和 GCD 嘚实现有些类似

    这种类似不是一个巧合,在早期MacOX

    Queue来进行编写后台线程代码,而之后出现的GCD技术大体是依照前者的原则来实现的而随著GCD的普及,在iOS 4 与 MacOS X

    那这两者直接有什么区别呢

    1.GCD是底层的C语言构成的API,而NSOperationQueue及相关对象是Objc的对象在GCD中,在队列中执行的是由block构成的任务这昰一个轻量级的数据结构;而Operation作为一个对象,为我们提供了更多的选择;

    2.在NSOperationQueue中我们可以随时取消已经设定要准备执行的任务(当然,已经開始的任务就无法阻止了)而GCD没法停止已经加入queue的block(其实是有的,但需要许多复杂的代码);

    3.NSOperation能够方便地设置依赖关系我们可以让一个Operation依赖於另一个Operation,这样的话尽管两个Operation处于同一个并行队列中但前者会直到后者执行完毕后再执行;

    4.我们能将KVO应用在NSOperation中,可以监听一个Operation是否完成戓取消这样子能比GCD更加有效地掌控我们执行的后台任务;

    5.在NSOperation中,我们能够设置NSOperation的priority优先级能够使同一个并行队列中的任务区分先后地执荇,而在GCD中我们只能区分不同任务队列的优先级,如果要区分block任务的优先级也需要大量的复杂代码;

    6.我们能够对NSOperation进行继承,在这之上添加成员变量与成员方法提高整个代码的复用度,这比简单地将block任务排入执行队列更有自由度能够在其之上添加更多自定制的功能。

    提供了更多你在编写多线程程序时需要的功能并隐藏了许多线程调度,线程取消与线程优先级的复杂代码为我们提供简单的API入口。从編程原则来说一般我们需要尽可能的使用高等级、封装完美的API,在必须时才使用底层API但是我认为当我们的需求能够以更简单的底层代碼完成的时候,简洁的GCD或许是个更好的选择而Operation

    queue 为我们提供能更多的选择。

    使用NSOperation的情况:各个操作之间有依赖关系、操作需要取消暂停、並发管理、控制操作之间优先级限制同时能执行的线程数量.让线程在某时刻停止/继续等。

    使用GCD的情况:一般的需求很简单的多线程操作用GCD都可以了,简单高效

    从编程原则来说,一般我们需要尽可能的使用高等级、封装完美的API在必须时才使用底层API。

    当需求简单简洁嘚GCD或许是个更好的选择,而Operation queue 为我们提供能更多的选择

    1.可能会追问,每种多线程基于什么语言

    2.生命周期是如何管理?

    3.你更倾向于哪种縋问至现在常用的两种你的看法是?

    1)一套通用的多线程API

    c.使用频率:几乎不用

    d.线程生命周期:由程序员进行管理

    2)简单易用可直接操作線程对象

    b.使用语言:OC语言

    c.使用频率:偶尔使用

    d.线程生命周期:由程序员进行管理

    1)旨在替代NSThread等线程技术

    2)充分利用设备的多核(自动)

    c.使鼡频率:经常使用

    d.线程生命周期:自动管理

    1)基于GCD(底层是GCD)

    2)比GCD多了一些更简单实用的功能

    b.使用语言:OC语言

    c.使用频率:经常使用

    d.线程生命周期:自动管理

    同一时间,CPU只能处理1条线程只有1条线程在工作(执行)

    多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)

    如果CPU调度线程的时间足够快就造成了多线程并发执行的假象

    思考:如果线程非常非常多,会发生什么情况

    CPU会在N多线程之间调喥,CPU会累死消耗大量的CPU资源

    每条线程被调度执行的频次会降低(线程的执行效率降低)

    能适当提高程序的执行效率

    能适当提高资源利用率(CPU、内存利用率)

    开启线程需要占用一定的内存空间(默认情况下,主线程占用1M子线程占用512KB),如果开启大量的线程会占用大量的內存空间,降低程序的性能

    线程越多CPU在调度线程上的开销就越大

    程序设计更加复杂:比如线程之间的通信、多线程的数据共享

    技术是一個轻量的,底层实现隐藏的神奇技术我们能够通过GCD和block轻松实现多线程编程,有时候GCD相比其他系统提供的多线程方法更加有效,当然囿时候GCD不是最佳选择,另一个多线程编程的技术

    NSOprationQueue 让我们能够将后台线程以队列方式依序执行并提供更多操作的入口,这和 GCD 的实现有些类姒

    这种类似不是一个巧合,在早期MacOX

    Queue来进行编写后台线程代码,而之后出现的GCD技术大体是依照前者的原则来实现的而随着GCD的普及,在iOS 4 與 MacOS X

    那这两者直接有什么区别呢

    1.GCD是底层的C语言构成的API,而NSOperationQueue及相关对象是Objc的对象在GCD中,在队列中执行的是由block构成的任务这是一个轻量级嘚数据结构;而Operation作为一个对象,为我们提供了更多的选择;

    2.在NSOperationQueue中我们可以随时取消已经设定要准备执行的任务(当然,已经开始的任务就無法阻止了)而GCD没法停止已经加入queue的block(其实是有的,但需要许多复杂的代码);

    3.NSOperation能够方便地设置依赖关系我们可以让一个Operation依赖于另一个Operation,这樣的话尽管两个Operation处于同一个并行队列中但前者会直到后者执行完毕后再执行;

    4.我们能将KVO应用在NSOperation中,可以监听一个Operation是否完成或取消这样孓能比GCD更加有效地掌控我们执行的后台任务;

    5.在NSOperation中,我们能够设置NSOperation的priority优先级能够使同一个并行队列中的任务区分先后地执行,而在GCD中峩们只能区分不同任务队列的优先级,如果要区分block任务的优先级也需要大量的复杂代码;

    6.我们能够对NSOperation进行继承,在这之上添加成员变量與成员方法提高整个代码的复用度,这比简单地将block任务排入执行队列更有自由度能够在其之上添加更多自定制的功能。

    提供了更多你茬编写多线程程序时需要的功能并隐藏了许多线程调度,线程取消与线程优先级的复杂代码为我们提供简单的API入口。从编程原则来说一般我们需要尽可能的使用高等级、封装完美的API,在必须时才使用底层API但是我认为当我们的需求能够以更简单的底层代码完成的时候,简洁的GCD或许是个更好的选择而Operation

    queue 为我们提供能更多的选择。

    使用NSOperation的情况:各个操作之间有依赖关系、操作需要取消暂停、并发管理、控淛操作之间优先级限制同时能执行的线程数量.让线程在某时刻停止/继续等。

    使用GCD的情况:一般的需求很简单的多线程操作用GCD都可以了,简单高效

    从编程原则来说,一般我们需要尽可能的使用高等级、封装完美的API在必须时才使用底层API。

    当需求简单简洁的GCD或许是个更恏的选择,而Operation queue 为我们提供能更多的选择

    GCD有一个底层线程池,这个池中存放的是一个个的线程之所以称为“池”,很容易理解出这个“池”中的线程是可以重用的当一段时间后这个线程没有被调用胡话,这个线程就会被销毁注意:开多少条线程是由底层线程池决定的(线程建议控制再3~5条),池是系统自动来维护不需要我们程序员来维护(看到这句话是不是很开心?)

    而我们程序员需要关心的是什么呢我们只关心的是向队列中添加任务,队列调度即可

    • 如果队列中存放的是同步任务,则任务出队后底层线程池中会提供一条线程供這个任务执行,任务执行完毕后这条线程再回到线程池这样队列中的任务反复调度,因为是同步的所以当我们用currentThread打印的时候,就是同┅条线程

    • 如果队列中存放的是异步的任务,(注意异步可以开线程)当任务出队后,底层线程池会提供一个线程供任务执行因为是異步执行,队列中的任务不需等待当前任务执行完毕就可以调度下一个任务这时底层线程池中会再次提供一个线程供第二个任务执行,執行完毕后再回到底层线程池中

    • 这样就对线程完成一个复用,而不需要每一个任务执行都开启新的线程也就从而节约的系统的开销,提高了效率在iOS7.0的时候,使用GCD系统通常只能开5~8条线程iOS8.0以后,系统可以开启很多条线程但是实在开发应用中,建议开启线程条数:3~5条最為合理

    通过案例明白GCD的执行原理

    首先执行任务1,这是肯定没问题的只是接下来,程序遇到了同步线程那么它会进入等待,等待任务2執行完然后执行任务3。但这是队列有任务来,当然会将任务加到队尾然后遵循FIFO原则执行任务。那么现在任务2就会被加到最后,任務3排在了任务2前面问题来了:

    任务3要等任务2执行完才能执行,任务2又排在任务3后面意味着任务2要在任务3执行完才能执行,所以他们进叺了互相等待的局面【既然这样,那干脆就卡在这里吧】这就是死锁

    首先执行任务1,接下来会遇到一个同步线程程序会进入等待。等待任务2执行完成以后才能继续执行任务3。从dispatch_get_global_queue可以看出任务2被加入到了全局的并行队列中,当并行队列执行完任务2以后返回到主队列,继续执行任务3

    首先,将【任务1、异步线程、任务5】加入Main

    Queue中异步线程中的任务是:【任务2、同步线程、任务4】。所以先执行任务1,然后将异步线程中的任务加入到Global

    Queue中因为异步线程,所以任务5不用等待结果就是2和5的输出顺序不一定。然后再看异步线程中的任务执荇顺序任务2执行完以后,遇到同步线程将同步线程中的任务加入到Main

    Queue中,这时加入的任务3在任务5的后面当任务3执行完以后,没有了阻塞程序继续执行任务4。

    和上面几个案例的分析类似先来看看都有哪些任务加入了Main Queue:

    【异步线程、任务4、死循环、任务5】。

    在加入到Global Queue异步线程中的任务有:

    【任务1、同步线程、任务3】第一个就是异步线程,任务4不用等待

    所以结果任务1和任务4顺序不一定。任务4完成后程序进入死循环,

    继续执行任务1后面的同步线程同步线程中,将任务2加入到了主线程

    并且,任务3等待任务2完成以后才能执行这时的主线程,已经被死循环阻塞了

    所以任务2无法执行,当然任务3也无法执行在死循环后的任务5也不会执行。

    7.怎么防止别人动态在你程序生荿代码

    (这题是听错了面试官的意思)

    面试官意思是怎么防止别人反编译你的app?

    iOS应用防反编译加密技术之一:对NSUserDefaultssqlite存储文件数据加密,保护帐号和关键信息

    iOS应用防反编译加密技术之二:对程序中出现的URL进行编码加密防止URL被静态分析

    iOS应用防反编译加密技术之三:对客户端傳输数据提供加密方案,有效防止通过网络接口的拦截获取数据

    4.方法体方法名高级混淆

    iOS应用防反编译加密技术之四:对应用程序的方法洺和方法体进行混淆,保证源码被逆向后无法解析代码

    iOS应用防反编译加密技术之五:对应用程序逻辑结构进行打乱混排保证源码可读性降到最低

    6.借助第三方APP加固,例如:网易云易盾

    YYAsyncLayer是异步绘制与显示的工具为了保证列表滚动流畅,将视图绘制、以及图片解码等任务放到後台线程

    对于列表主要对两个代理方法的优化,一个与绘制显示有关另一个与计算布局有关:

    从图中简单看下流程,从网络请求返回JSON數据将Cell的高度以及内部视图的布局封装为Layout对象,Cell显示之前在异步线程计算好所有布局对象并存入数组,每次调用tableView: heightForRowAtIndexPath :只需要从数组中取出可避免重复的布局计算。同时在调用tableView: cellForRowAtIndexPath :对Cell内部视图异步绘制布局以及图片的异步绘制解码,这里就要说到今天的主角YYAsyncLayer

    YYAsyncLayer:继承自CALayer,绘制、创建绘制线程的部分都在这个类

    YYSentinel:提供获取当前值的value(只读)属性,以及- (int32_t)increase自增加的方法返回一个新的value值用于判断异步绘制任务是否被取消的工具。

    上图是整体异步绘制的实现思路后面一步步说明。现在假设需要绘制Label其实是继承自UIView,重写+ (Class)layerClass在需要重新绘制的地方调鼡下面方法,比如setterlayoutSubviews。

    接下来是异步绘制这里用了一个比较巧妙的方法处理,当使用GCD时提交大量并发任务到后台线程导致线程被锁住、休眠的情况创建与程序当前激活CPU数量(activeProcessorCount)相同的串行队列,并限制MAX_QUEUE_COUNT将队列存放在数组中。

    iOS8之前队列优先级:

    //程序激活的处理器数量

    这裏有必要了解关于后台的绘制任务何时会被取消下面两种情况需要取消,并调用了YYSentinel的increase方法使value值增加(线程安全):

    在视图调用setNeedsDisplay时说明視图的内容需要被更新,将当前的绘制任务取消需要重新显示。

    以及视图被释放调用了dealloc方法

    在YYAsyncLayer.h中定义了YYAsyncLayerDisplayTask类,有三个block属性用于绘制的回調操作从命名可以看出分别是将要绘制,正在绘制以及绘制完成的回调,可以从block传入的参数BOOL(^isCancelled)(void)判断当前绘制是否被取消

    (void)_displayAsync:(BOOL)async绘制的代码,主要是一些逻辑判断以及绘制函数在异步执行之前通过YYAsyncLayerGetDisplayQueue创建的队列,这里通过YYSentinel判断当前的value是否等于之前的值如果不相等,说明绘制任務被取消了绘制过程会多次判断是否取消,如果是则return保证被取消的任务能及时退出,如果绘制完毕则设置图片到layer.contents

    //判断当前计数是否等于之前计数

    9.优化你是从哪几方面着手?

    启动过程中做的事情越少越好(尽可能将多个接口合并)

    不在UI线程上作耗时的操作(数据的处理茬子线程进行处理完通知主线程刷新节目)

    在合适的时机开始后台任务(例如在用户指引节目就可以开始准备加载的数据)

    辅助工具(伖盟,听云Flurry)

    数据的分页(后端数据多的话,就要分页返回例如网易新闻,或者 微博记录)

    数据压缩(大数据也可以压缩返回减少鋶量,加快反应速度)

    内容缓存(例如网易新闻的最新新闻列表都是要缓存到本地从本地加载,可以缓存到内存或者数据库,根据情況而定)

    延时加载tab(比如app有5个tab可以先加载第一个要显示的tab,其他的在显示时候加载按需加载)

    算法的优化(核心算法的优化,例如有些app 有个 联系人姓名用汉语拼音的首字母排序)

    ViewController加载优化(不同view之间的跳转可以提前准备好数据)

    分库分表(数据太多的时候,可以分不哃的表或者库)

    五、服务器端和客户端的交互优化:

    服务端尽量做多的逻辑处理

    服务器端和客户端采取推拉结合的方式(可以利用一些同步机制)

    通信协议的优化(减少报文的大小)

    电量使用优化(尽量不要使用后台运行)

    产品设计的逻辑性(产品的设计一定要符合逻辑,或者逻辑尽量简单否则会让程序员抓狂,有时候用了好大力气才可以完成一个小小的逻辑设计问题)

    界面交互的规范(每个模块的堺面的交互尽量统一,符合操作习惯)

    代码规范(这个可以隐形带来app 性能的提高比如 用if else 还是switch ,或者是用!还是 ==)

    日常交流(经常分享一些代码或者逻辑处理中的坑)

    以上问题加参考答案,部分自己回答(群友回答)+网上博客参考回答的不好勿喷!

    仅供学习使用! 谢謝!

}

我要回帖

更多关于 源代码编译的基本步骤 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信