美文网首页
iOS知识点

iOS知识点

作者: 肉肉要次肉 | 来源:发表于2017-10-24 18:27 被阅读9次

    1、内存的几大区域

    iOS的内存分布区域大致分为:栈区(stack)、堆区(heap)和全局静态区(static)。

    栈区:主要存放局部变量函数的参数值等相关变量,由编译器自动分配并释放。栈是系统数据结构,对应线程/进程是唯一的。

    优点:是快速高效,缺点时有限制,数据不灵活。[先进后出]


    堆区:存放alloc,new等关键字生成的对象,由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收。(ps:虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存,释放内存匹配是良好程序的基本要素。而且,若程序员不释放,会出现内存泄露。)

    优点:是灵活方便,数据适应面广泛,但是效率有一定降低。


    全局静态区:主要存放静态数据全局数据常量

    以上是针对静态数据、全局数据和常量的一个区分。

    PS:

    1.申请后的系统是如何响应的?

    栈:由编译器自动分配和释放,只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

    堆:操作系统中有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,并将该结点的空间分配给程序。由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

    2.申请大小的限制是怎样的?

    栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域。是栈顶的地址和栈的最大容量是系统预先规定好的,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数 ) ,如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    打个比喻来说:

    使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

    使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

    2、多线程

    多线程分为:pthread、NSTread、GCD和NSOperation四种。

    多线程的原理:

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

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

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

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

    CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源,每条线程被调度执行的频次会降低,也就是说线程的执行效率降低。

    多线程的优点:

    能适当提高程序的执行效率,能适当提高资源利用率(CPU、内存利用率)

    多线程的缺点:

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

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

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

    更倾向于哪一种多线程呢?

    GCD技术是一个轻量的,底层实现隐藏的神奇技术,我们能够通过GCD和block轻松实现多线程编程。有时候,GCD相比其他系统提供的多线程方法更加有效,当然,有时候GCD不是最佳选择。另一个多线程编程的技术NSOprationQueue让我们能够将后台线程以队列方式依序执行,并提供更多操作入口,这和GCD的实现有些类似。

    这种类似不是一个巧合,在早期,MacOX 与 iOS 的程序都普遍采用Operation Queue来进行编写后台线程代码,而之后出现的GCD技术大体是依照前者的原则来实现的,而随着GCD的普及,在iOS 4 与 MacOS X 10.6以后,Operation Queue的底层实现都是用GCD来实现的。

    3、怎么防止别人反编译你的app?

    1)本地数据加密

    对NSUserDefults,sqlite存储文件数据加密,保护账号和关键信息。

    2)URL编码加密

    对程序中出现的URL进行编码加密,防止URL被静态分析

    3)网络传输数据加密

    对客户端传输提供加密方案,有效防止通过网络接口的拦截获取数据

    4)方法体,方法名高级混淆

    对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码

    5)程序结构混排加密

    对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低

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

    4、优化从几方面入手

    一、首页启动速度

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

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

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

    尽量减小包的大小

    优化方法:

    量化启动时间、启动速度模块化、辅助工具(友盟、听云、Flurry)

    二、页面浏览速度

    json的处理:(iOS自带的NSJSONSerialization,Jsonkit,SBJson)

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

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

    内容缓存:(将页面信息缓存到本地,从本地加载,可以缓存到内存,或者数据库,根据情况而定)

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

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

    三、操作流畅度优化

    tableView优化(tableView cell的加载优化)

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

    四、数据库的优化

    数据库设计上面的重构

    查询语句的优化

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

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

    客户端尽量减少请求

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

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

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

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

    5、runloop内部实现逻辑

    可以看到,实际上RunLoop就是这样一个函数,气内部是一个do-while循环。当你调用CFRunLoopRun()时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。

    。。。

    相关文章

      网友评论

          本文标题:iOS知识点

          本文链接:https://www.haomeiwen.com/subject/mkotpxtx.html