养成良好的编码习惯(iOS)

2016-12-12  本文已影响0人  玄裳

@Famulei.

强制采用一套严格的技术标准并不是一个好主意,但是标准对于团队组织非常有用,因为标准有助于减少项目中随意出现的诸多分歧。如果你的团队反对采用严格的标准,那么可以考虑一些其他的选择,如灵活的指导原则、一些建议,或者一组能够表现最佳实践的例子。

命名规则

为什么要有规则

何时采用命名规则

类名

协议

   if ([self.cell.delegate respondsToSelector:@selector(cell:didClickImageAtIndex:withLongPress:)]){
 
      [self.cell.delegate cell:self.cell didClickImageAtIndex:index withLongPress:NO];
  
   }

Variable Names 变量名

你可不能像给狗取名字哪有给变量名,仅仅因为它可爱或者听上去不错。变量和变量名就本质而言是同一食物。变量的好与坏很大程度上取决于它命名的好坏。在给变量命名的时候请谨慎小心。

eg:

     v      vs    headView

    mlbl    vs    nameLabel

    VC1    vs    registerViewController

从上述的例子比较看出,一个好的变量名是可读的,易记的和具有描述性的。

变量命名时最重要的考虑事项 :

该名字要完全,准确地描述出该变量所代表的事物。通常对变量的描述

就是最佳的变量名。这种名字容易阅读,因为其中并不包含晦涩的缩写,

同时也有歧义,因为它是对该事物的完整描述,不会和其他事物混淆,

因此也容易记忆。

Const 常量

常量使用由全部大写的多个单词组成的说明型名称,每个单词之间用下划线分隔。声明常量时,要使用Const语句以及常量名、它的数据类型和它的值。

下面是一些使用常规命名规范的常量名称示例:

eg:

      ACCESS_CONNECTSTRING
      YY_EXTERN_C_BEGIN
      API_MAX_STRINGBUFFER

常量名(如宏定义、枚举、静态局部变量等)推荐参考Apple开发文档命名。以小写字母k开头.官方说法:k表示Const (谁让人家Apple喜欢呢)

//大家经常看到的

eg:

      kMainScreenWidth
      kMainScreenHeight

我就是想要使用缩写(遇到任性的宝宝):

eg:

   x1 , y2 , m3 ,z4  ( 臣妾真的猜不到 - - )

枚举常量

  1. 使用枚举来定义一组相关的整数常量

  2. 枚举常量与其typedef命名遵循函数命名规则。

C语言风格的enum定义枚举类型

    enum {

      UIViewAnimationTransitionNone,                       
      UIViewAnimationTransitionFlipFromLeft,
      UIViewAnimationTransitionFlipFromRight,
      UIViewAnimationTransitionCurlUp,
      UIViewAnimationTransitionCurlDown,

    } UIViewAnimationTransition;

//位移操作枚举定义

   enum {

     UIViewAutoresizingNone                 = 0,
     UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
     UIViewAutoresizingFlexibleWidth        = 1 << 1,
     UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
     UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
     UIViewAutoresizingFlexibleHeight       = 1 << 4,
     UIViewAutoresizingFlexibleBottomMargin = 1 << 5

   };  typedef NSUInteger UIViewAutoresizing;

枚举值一般是4个字节的int值,在64位系统上是8个字节。iOS6以后苹果引入了两个宏来重新定义这两个枚举类型,将enum定义和typedef合二为一,并且采用不同的宏来从代码角度来区分。

NS_OPTIONS一般用来定义位移相关操作的枚举值。

通用情况,推荐使用NS_ENUM。NS_OPTIONS一般用来定义具有位移操作或特点的情况。例如:

   typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    
        UIViewAnimationTransitionNone,//默认从0开始
        UIViewAnimationTransitionFlipFromLeft,
        UIViewAnimationTransitionFlipFromRight,
        UIViewAnimationTransitionCurlUp,
        UIViewAnimationTransitionCurlDown,

   };


   typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {

        UIViewAutoresizingNone                 = 0,
        UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
        UIViewAutoresizingFlexibleWidth        = 1 << 1,
        UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
        UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
        UIViewAutoresizingFlexibleHeight       = 1 << 4,
        UIViewAutoresizingFlexibleBottomMargin = 1 << 5

  };

方法命名

eg:

      - (void)selectItemAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;

      - (void)appendPartWithInputStream:(NSInputStream *)inputStream name:(NSString *)name fileName:(NSString *)fileName length:(int64_t)length mimeType:(NSString *)mimeType;

      - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters error:(NSError * __autoreleasing *)error;

准确使用对仗词

      add/remove                     begin/end                     insert/delete

      increment/decrement             show/hide                    create/destory

      open/close                      lock/unlock                  source/target

      first/last                       max/min                      start/stop

      get/put                         next/previous                    up/down

      get/set                          old/new                        high/low

经典命名规则

该命名法是在每个变量名的前面加上若干表示数据类型的字符。

基本原则是:变量名=属性+类型+对象描述。

如i表示int,所有i开头的变量命都表示int类型。

s表示String,所有变量命以s开头的都表示String类型变量。

正如它的名称所表示的那样,是指混合使用大小写字母来构成变量和函数的名字。驼峰命名法跟帕斯卡命名法相似,只是首字母为小写,如userName。因为看上去像驼峰,因此而得名。

布局与风格

布局与风格并不影响执行速度、内存使用量等方面程序的布局。编排出色的代码会带来视觉上和思维上的愉悦,这是非程序员的人不能感受到的。如果你做的是合作项目,这块内容还是蛮重要的,尽量统一大家的风格。

好布局有什么用

布局技术

eg: //Method 分组

    #pragma mark - View lifeCycle

    #pragma mark - Getter/Setter

    #pragma mark - Init methods

    #pragma mark - Action methods

    #pragma mark - Common methods

    #pragma mark - UIActionSheetDelegate

    #pragma mark - UIImagePickerControllerDelegate

    #pragma mark - UITableViewDelegate Methods

    #pragma mark - UITableViewDataSource Methods

    #pragma mark - UIScrollViewDelegate Methods

eg: //属性

     @property (nonatomic, readonly, strong) NSDictionary *statuCodeToMessageDictionary;
  1. property 后留空格

  2. 修饰符“,”后留空格

  3. 修饰符“()”后留空格

  4. 所有变量的类名后留空格

  5. 类型标识符和尖括号内的协议名之间不能有任何空格

  6. 属性的参数应该按照下面的顺序排列: 原子性->读写->内存管理

(这些修饰符被修改的可能性从高到底应为:内存管理 > 读写权限 >原子操作)

  1. 如无特别情况,使用nonatomic修饰,atomic带来的互斥锁特别影响性能。

eg: //方法

    - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;

1.方法返回值前留空格

2.方法返回值后不留空格

3.左括号和方法名在同行并有空格隔开

4.多个参数的方法换行并以冒号对齐

eg://method 推荐写法(不完全为了美观)

    - (BOOL)validateResponse:(NSHTTPURLResponse *)response 
                        data:(NSData *)data
                       error:(NSError *__autoreleasing *)error;

//不推荐写法(参数很多的情况,可读性很差)
    - (BOOL)validateResponse:(NSHTTPURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error;

eg: //常用的字符串(推荐写法)

     NSString *string = @"Rose";

     //不推荐写法
     NSString*string=@"Rose";

eg: //create UILabel 推荐写法 (组织结构明了,易于修改,可维护性强)

     UILabel *testLabel = [[UILabel alloc]init];
     testLabel.frame = CGRectMake(50, 50, 50, 50);

     testLabel.text = @"The cute Rose";
     testLabel.textColor = [UIColor yellowColor];

     [self.view addSubview:testLabel];


     //不推荐 (凌乱, 臃肿,简直不想看)
     UILabel*testLabel=[[UILabel alloc]init];
     testLabel.frame=CGRectMake(50, 50, 50, 50);
     testLabel.text=@"The cute Rose";
     testLabel.textColor=[UIColor yellowColor];
     [self.view addSubview:testLabel];
  1. 段落之间使用空行

  2. 单语句代码块的格式要前后统一

  3. 对于复杂的表达式,将条件分隔放在多行上

  4. ...

注释

对于精心编写的代码而言,注释不过是美丽衣裳上的小饰物而已。注释的种类:

重复代码

解释代码

代码标记

概述代码

代码意图说明

注释单行或多行

行尾注释用于数据声明

避免用行尾注释存放维护注记 (记录修改或者错误编号)

用行尾注释标记块尾

注释控制结构

eg:

     /**

      基本地址URL,接口特殊性需要其他baseURL,可以覆盖此方法 默认为空

      @return 基本地址的URL

    */

    - (NSString *)baseURL;

高质量的子程序

什么是子程序?

子程序是为实现一个特点的目的而编写的一个可被调用的方法(method)或者过程(procedure)。

创建子程序的正当理由

创建类的很多理由也是创建子程序的理由

子程序设计

是最强也是最好的一种内聚性,让一个子程序仅执行一项操作。

是指子程序包含有需要按特定书序执行的操作,需要共享数据,而且只有全部执行完毕后才完成一项完整的功能。

是指一个子程序中的不用操作使用了同样的数据,但不存在其他任何联系。

是指含有一些因为需要同时执行才放到一起的操作的子程序。

是指一个子程序的操作是按特定的顺序进行的。

是指若干操作被放入同一个子程序中,通过传入的控制标志选择执行其中的一项操作。

是指子程序中的各个操作之间没有任何可以看到的关联。

宏定义

C语言提供的三种预处理功能的其中一种,分别为:宏定义、文件包括、条件编译。宏定义和操作符区别是:宏定义制作替换,不做计算,也不做表达式求解。

eg: // 简单的宏定义

      #define STATUS_BAR_HEIGHT 20

eg: // 代码块宏定义

      #define ALERT(text) {UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:(text) delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];[alert show];}

断言

断言是开发期间使用的、让程序在运行时进行自检的代码(通常是一个子程序或者宏)。

建立自己的断言机制

例如YYKit里面:

      #define YYAssertNotNil(condition, description, ...) NSAssert((condition), (description), ##__VA_ARGS__)

      #define YYCAssertNotNil(condition, description, ...) NSCAssert((condition), (description), ##__VA_ARGS__)

      #define YYAssertMainThread() NSAssert([NSThread isMainThread], @"This method must be called on the main thread")

      #define YYCAssertMainThread() NSCAssert([NSThread isMainThread], @"This method must be called on the main thread")

使用断言的建议

异常

异常时把代码中的错误或异常事件传递给调用方代码的一种特殊手段。

使用@try、catch捕获异常:

      @try {

           // 可能会出现崩溃的代码

      }

      @catch (NSException *exception) {

          // 捕获到的异常exception

      }

     @finally {

         // 结果处理

      }

警告(视团队需求而定)

信仰问题

”特定的标准”的细节往往没有“存在某个标准”重要。我们都在向一个相对标准的规则靠近。没必要在一些编码风格的细节差异上产生斗争。只要清晰明了,对项目没有损失就好。

个人性格(题外话)

本文参考:

小菲菲总结了份规范文档

http://xuyafei.cn/post/language/cocoadai-ma-feng-ge-zhi-nan-zhi-ming-ming-gui-fan

<<代码大全>>

我们公司正在招聘前端开发工程师和PHP开发工程师,欢迎加入我们的Famulei.com,坐标上海。


养成良好的编码习惯(iOS)
上一篇下一篇

猜你喜欢

热点阅读