从0开始看一个项目

在着手一个项目前先读文档(如果有文档的话)。尽管读了文档你不一定知道每一个代码的细节,但是如果你了解那个问题的话,你一定知道怎么写可以写出一个满足文档的内容。这个时候大脑里面就可以有个框架,先猜一猜,然后看代码,事半功倍。找不到好的文档,就看他的测试用例,也是有一样的功效的。因为测试都是从文档出发编写的,而不是从代码出发编写的。找不到文档和测试用例?那就直接Gank吧。

读代码要层次化、带着问题去阅读。首先整体了解这个软件是干什么?解决什么问题?包含哪些大的模块,各个模块的作用是什么,各个模块的调用关系怎么样?然后对于每一个模块,这个模块是干什么的?为什么要有这个模块?这个模块怎么实现的?最后细化到每一个包,每一个类,每一个函数方法。从上到下,一一击破每一个问题,认真去思考他这样设计、写代码的好处,因为好的软件都会满足这种从抽象->具体的原则的。

在开始读具体代码前定位好所有要读的文件,知道他们的位置和名字,设计良好的工程光看工程的目录结构和文件名就能知道个大概功能了。事实上阅读代码的难易程度70%取决于代码书写的规范程度,写乱掉的代码,大师也读不懂。之后根据你对目录结构的理解确定文件阅读的顺序(我反正都是从main函数开始读的)。你最好对设计模式有一定了解,否则你读面向对象的code时会经常无法理解code为啥要弄得这么层层嵌套。阅读代码一个最重要的提升水平的地方就是理解好的代码如何合理使用设计模式。基本的阅读起点都会选择main函数或者类的构造函数。然后把自己想象成cpu执行程序那样去阅读你的代码。遇到需要跳转函数时,不要急于跳转,以了解函数功能和输入输出为目标,读代码最忌讳的是不抓结构抓细节,只见树木不见森林,比起某个函数具体功能来说对结构的全局把握更重要。功能了解清楚后继续跳回来(这里就可以区分代码写的优不优秀,优秀的代码光看函数名字就知道功能,连跳转都不用)。结构弄清楚了,知道程序怎么跑了,source code的精华你已经读了60%了,之后根据需要再对具体函数深入分析,到这里整个代码已经被你扒光了,没什么神秘了。

阅读代码有两种模式:top-downbottom-up。Top-down 模式,就是先设定一个 use case,比如说打开一个文件。然后静态跟着代码看,或者用 debugger 跟着看。每次出现函数调用的时候,把函数的执行层次纪录下来。大致如下:

func1( )
   func2(  )
       func(  )
   func3(  )

这种图表很随意,你可以根据自己的需要增加信息,可以把重要的「实际参数」一直标下来,画函数调用图,然后标注每个函数在干什么。不过这个图无法清楚地表明一个变量的轨迹,需要另外的图来标示变量的变化轨迹。要是想提高阅读代码的速度,归根结底要多读多写。熟悉程序的基本构成单元(例如循环、分支)的常见写法,各种lib, api的调用方式。这样阅读深层次代码不用再回头查形式参数到底指什么。这个图的基本作用是防止在阅读深层次代码时忘记总体执行层次。Top-down 模式进行到一定层次,往往会发现虽然图画了出来,但还是无法了解程序在干什么。这时需要转入 bottom-up 模式,一直深入到最底层,给能了解作用的底层函数一个一个的写文档。当然这时的文档是完全底层的观点。bottom-up的阅读方法,有时候会一头扎进去,出不来了。这种方式适合读一些比较优秀的开源项目的代码,也会很好地提高内功。然后就是不断在两个模式之间转换,不断的细化两种模式的理解。

最后,对于OC工程可以去GitHub找UIViewController-Swizzled这个库,拉下来放到项目里,他有什么用呢?他可以把每个页面的类名打出来。而且有层次结构,也就是说你只需要打开项目点点点,就知道这个App运行的顺序了。

项目