iOS开发,事半功倍基本心得(一)


最近一直在为公司3.0的app加班加点,前段时间总算完成了,有空坐下来写写东西。既然是第一篇关于IOS开发的文章就先写点自己这些年学到最最基本的经验吧。一些编程中的小细节很容易被忽略,但是往往细节可以让自己变得更专业。

主要是想说下Project的结构。由于Project里的内容是否分组或者整洁,基本不会影响做出来的APP的效果,所以常常被忽视。其实不然,在很多工作项目中(特别是大型项目),我们都会和其他程序员或者设计师合作。而设立一个整洁的项目结构对合作开发非常有帮助,对后期Bug修复或者Code Review也都会事半功倍。Project的结构就犹如家庭装潢的内部排线,排线的好坏通常是无法从房屋的外观判断的。但是一旦需要排查问题或者修改线路时,一个好的内部系统就能让一切变得井井有条,也可以体现制作者的专业性。

就根据我个人的经验判断,好的Project 结构包括了合理的命名规则,Project内容分组,常用代码的封装,和使用有效的Comments。下面我们就一条一条的来看。

1. 第一是合理的命名规则。

其实这条还是比较抽象的,因为不一样的项目可能会有一些不一样的需求。但是我主要想说一些最最基本和几乎通用的规则。

非常推荐使用Class prefix name就是Class的前缀名,使用前缀名能够一定程度的避免你的Class和其他Framework / Library中的内容重名,也能够让你在Import或使用Class的时候比较方便寻找。通常都会推荐用几个大写字母来作为前缀名,Apple的iOS SDK里全部都使用了Prefix,比如我们经常会用到的以NS为前缀的Foundation和Application Kit里的Class,以UI开头的UIKit,以CL开头的Core Location 等等。

在命名Class的时候尽量保证它的名字能够涵盖他的类别和用途。比如你有一个UIViewController是用来显示User Profile的, 那你就可以把它命名为在XX(前缀)UserProfile(用途)ViewController(类别)。这样的话如果在一个比较大型的工程中,你或者你的同事只需要知道用途或者类别就可以很快的锁定目标。而且我推荐把比如使用在XXUserProfileViewController内部的自定义的subview,都用XXUserProfile来前缀,其实依然是遵守上述的命名规则,XX(前缀)UserProfileAddress(用途)Cell(类别),这样能够在后面的文件分组里面起到比较好的效果,而且可以很快查到所有和UserProfile相关的内容。

在命名Method的时候也应该选择能包括这个Method功能,所需的参数类别和关系的名字,但是尽量简洁。当然简洁只是相对的,更重要的就是能够让其他程序员包括你自己在几个月后甚至一年后一看就能大约明白这个Method的用途和条件。就连Apple提供的SDK里面都有一些超长的Method,但是重要的是一看就大概知道这个Method能干什么和需要什么参数,比如从NSBitmapImageRep里面可以找到的:

- (id)initWithBitmapDataPlanes:(unsigned char **)planes  
                    pixelsWide:(NSInteger)width
                    pixelsHigh:(NSInteger)height
                 bitsPerSample:(NSInteger)bps
               samplesPerPixel:(NSInteger)spp
                      hasAlpha:(BOOL)alpha
                      isPlanar:(BOOL)isPlanar
                colorSpaceName:(NSString *)colorSpaceName
                  bitmapFormat:(NSBitmapFormat)bitmapFormat
                   bytesPerRow:(NSInteger)rowBytes
                  bitsPerPixel:(NSInteger)pixelBits;

Apple的程序员手册里面也对Method命名规则有不少的叙述,比如说尽量不要用缩写,尽量用意义明确的词,等。

在我们3.0的App中也有一些比较长的Method,但是我们尽量保持他的含义可以像读短文一样容易理解,比如:

+ (NSMutableArray *)animateNavBarFromColor:(UIColor *)fromColor  
                                   toColor:(UIColor *)toColor 
                                  duration:(NSTimeInterval)duration;

+ (NSMutableAttributedString *)generateAttributedStringFromString:(NSString *)string 
                                                     withFontName:(NSString *)fontName 
                                                         fontSize:(float)fontSize 
                                                    textAlignment:(NSTextAlignment)alignment 
                                                    lineBreakMode:(NSLineBreakMode)lineBreakMode;

这两个是我们项目中得Public Method的名字,我觉得这样的Method的名字还是比较可以接受的。哪怕对我们的项目完全不理解的人也应该可以明白这两个Method的大概功能。而且一些常用的而且意义明确的名字就可以用简短的方式来表达,比如说NavigationBar,一般称作NavBar不会有任何的歧义,也遵守了简洁的规则。

2. 接下来让我介绍下,如何较好的将一个大型Project其中的内容分组。

其实不论Project的大小,我们都应该将View Controllers, Views, Objects, Frameworks, Resources,等等不同类型的文件,都按照他们的种类和具体用途进行了归类,这样在日后修改和添加内容时候都会同样的事半功倍。因为大中型的Project中势必使用了大量的View Controllers和自定义的Object Class和Custom View. 如果成百上千个文件无须的罗列在一个项目中,那种混乱程度是可以让一个原本20分钟的Bug fix延长到一个小时。当然很多时候,如果你知道部分文件名的话,Cmd+shift+O还是我们最好的朋友(所以合理的命名规则这块是非常重要)。而且分组的重要性在你不是很确定文件名的时候,比如review你同事的code或者在一位同事离职或休假的时候有紧急的bug fix,明确的分组就好像一张好的地图一样,很容易就找到你的目标。

我相信文件分组还是被相对普遍运用的,但代码的分组常常会被忽略。如同刚才所说的,你在一堆文件中总算找到你的的目标文件了。而有时候一个View Controller可能有几百上千行的代码,如果把代码也按照类型和功能分组的话,这样能进一步的提升效率,减少不必要的痛苦。
合理的使用#pragma mark - 是代码分组最简单而且最有效的方法,好像这张图片里的,

我们把代码按照他们的基本类型和功效使用#pragma mark - 来区分,比如:

#pragma mark - View Controller Life Cycle  
#pragma mark - API Calls

然后每次你只要知道大概的目标代码,就可以在导航栏里点击代码这块,很容易就能找到结果。

to be continue..