asunquan.com

不忘初心 不止于行

职场新人 iOS菜鸟 就职于搜狐畅游 从事iOS/tvOS的SDK开发 对于游戏市场有点点了解 平日和一只小Corgi同吃同睡


iOS开发规范文档

iOS开发规范文档

[TOC]

工程资源

  • 使用framework作为SDK的呈现形式

  • 设置search path时, 使用相对路径替代绝对路径, 使用输出SDK目录路径替代本机DerivedData路径
  • 资源bundle文件夹不需要进行编译
  • 图片资源命名规则: 模块_控件类型_功能_状态@几倍图.图片类型

命名规则

  • 禁止使用拼音命名, 要使用正确的英文拼写进行命名
  • 命名使用驼峰命名法, 类名使用大驼峰命名法, 其余使用小驼峰命名法
  • 属性, 方法, 参数, 变量, 常量等的命名应该具有上下文或者全局的一致性, 相同类型或具有相同作用的变量的命名方式应该相同或相似, 并且保持清晰和简洁
  • 方法, 属性命名小写字母开头(以大写缩略词开始的除外), 文件夹大写字母开头
  • 自营SDK文件前缀LM, 其他SDK文件前缀LT
  • category中使用lm_lt_前缀与原有方法进行区分

  • 不要使用_作为私有方法的开头

  • Target-Action的方法命名时加Action, 使用(id)sender代表触发对象

    - (void)clickAction:(id)sender;
    

代码排版

  • 方法之间空一行, 单个方法不要超过80行, 如果方法过长需要抽出部分代码分步执行

  • 实例方法-和类方法+(空一格, 方法参数间空一格

  • 方法实现的{}独占一行, 方法内部的{}不需要独占一行, 包括if, switch等, 但是{必须与前一个字符空一格, block{需要与参数结尾的)间空一格, void除外

  • 参数个数在两个以内不需要换行对齐, 两个以上需要换行并保证以:对齐(特殊情况除外, 例如:在该行位置过于靠后或换行之后:无法对齐)

    - (void)callMethod:(NSString *)value1
                value2:(NSString *)value2
                value3:(NSString *)value3
    {
        if (value1) {
            return;
        }
          
        [Object callMethodB:value1 value2:value2];
          
        [Object callMethodC:value1
                     block1:^{
                         NSLog(@"a");
                     }
                     block2:^(NSString *args2) {
                         NSLog(@"a");
                     }];
          
        [Object callMethodD:value1
                     block1:^(NSString *args1) {
                         NSLog(@"a");
                     }
                     block2:^(NSString *args2) {
                         NSLog(@"a");
                     }];
                      
         NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:reqURL cachePolicy:self.cachePolicy timeoutInterval:self.timeoutInterval];
    }
    
  • 指针*与实例名之间没有空格

  • 属性的定义, @property(, )类名, 类名*间必须有空格, 必须写明是否原子性, 指针类型

    @property (nonatomic, strong) NSString *someString;
    
  • 声明一个变量时, 指针*靠近变量名

    NSString *someString = @"SomeString";
    
  • 如果一个方法有超过2个参数(block回调除外), 需要考略将参数封装成对象

  • 相同功能的代码需要进行封装, 不要使用cv操作

  • 使用#pragma mark -对实现文件进行方法分类

    #pragma mark - life cycle
    #pragma mark - setter && getter
    #pragma mark - public method
    #pragma mark - action
    #pragma mark - private method
    #pragma mark - delegate && dataSource
    
  • 尽量保持代码的整洁, 不要添加过多无意义的log和注释

方法调用

  • 使用属性代替成员变量, 使用self.代替_(setter和getter方法中除外)

  • 使用.语法代替[]调用无参数且要使用返回值的方法

  • 尽量使用lazy load, 在使用时再去初始化对象

  • 重载系统方法的时候, 如无特殊情况均需要先调用super的方法

  • 使用new代替alloc.init初始化对象

  • 创建单例对象方法, 使用instancetype作为返回值类型, 并且统一使用sharedInstance作为方法名

    + (instancetype)sharedInstance;
    
  • 创建单例对象时, 使用线程安全的方式创建完全单例

    static Class *instance = nil;
      
    + (instancetype)sharedInstance
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = Class.new;
        });
        return instance;
    }
      
    + (instancetype)allocWithZone:(NSZone *)zone
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [super allocWithZone:zone];
        });
        return instance;
    }
    
  • 初始化方法使用默认代码格式

    - (instancetype)init 
    {
        self = [super init];
        if (self) {
            // do something
        }
        return self;
    }
    
  • 使用字面量快速构造对象

    类型 语法 示例
    NSString @”文字” @”aString”
    NSNumber @数字 @1
    NSArray @[数组内容] @[@1, @2]
    NSDictionary @{键 : 值} @{@”key” : @”value”}
  • NSArrayNSDictionary使用字面量创建时, 内部每一个元素需要对齐

    NSArray *someItems = @[@"ABC",
                           @"BCD",
                           @"CDE"];
          
    NSDictionary *someKeyValues = @{@"Key1" : @"Value1",
                                    @"Key2" : @"Value2"};
      
    NSDictionary *someKeyValues = @{@"Key1" : @"Value1",
                                    @"Key2" : @"Value2"
                                    }.lm_newKeyValues;
    
  • 如果需要操作的一组元素需要去重, 请使用NSSet而不是NSArray

  • 头文件中只暴露一些必要公开的方法, 属性, 私有方法和属性, 尽量写在实现文件中

  • 不要使用宏定义的方式创建常量, 因为宏定义不会进行类型检测

  • 常量应该在实现文件中进行复制, 如果需要暴露给外部在头文件中extern出来, 使用k标识常量, 无需暴露的使用static修饰

    .h
    extern NSString *const kSomeConstant;
    .m
    NSString *const kSomeConstant = @"someConstant";
      
    .m
    static NSString *const kSomeConstant = @"someConstant";
    
  • 使用NS_ENUMNS_OPTIONS宏来定义枚举值

    typedef NS_ENUM(NSUInteger, SomeEnum) {
        SomeEnumA,
        SomeEnumB,
        SomeEnumC,
    };
      
    typedef NS_OPTIONS(NSUInteger, SomeEnum) {
        SomeEnumA = 1 << 0,
        SomeEnumB = 1 << 1,
        SomeEnumC = 1 << 2,
    };
    
  • if语句后面必须要有{}

  • switch语句每一个case都要有{}

  • if, else, switch, while需要另起一行

    if (condition) {
        statements
    }
    else {
        statements
    }
    
  • 多于2个逻辑表达式必须用参数分割成多个有意义的bool变量

  • 在条件判断中, 尽量把逻辑写在判断之后

    + (void)someMethod 
    {
        if (!someCondition) {
            return;
        }
          
        // do something
    }
    
  • 在条件判断时, 需要省略和nil,YES, NO比较的部分

  • 尽量避免条件语句的嵌套

  • 一目运算符!, ++, --不需要空格间隔

    if (!hidden) {
          
    }
    
  • 二目运算符+, -, *, /, %, =, >, <, ==, !=, >=, <=, &&, ||, &, ^, |等运算符左右两侧各空一格

    NSInteger one = 1;
    NSInteger two = 2;
      
    NSInteger three = one + two;
    
  • 三目运算符? :?:外都要与?he:两侧各空一格

    NSString *someValue = condition ? @"A" : @"B";
      
    NSString *someValue2 = someValue ?: @"B";
    
  • 三目运算符不要超过两层判断

  • 如果方法是为了获取某一个值, 不要在方法前面加get

    + (UIImage *)blurImage;
    
  • 尽量使用block作为回调手段

  • 调用block回调前必须判断block是否为nil

  • 在声明遵守的协议时, 尽量把声明写在实现文件中, )<间空一格

    @interface SomeClass () <SomeDelegate>
          
    @end
    
  • 调用delegate回调前必须判断该协议方法是否被实现

注释规则

  • 头文件中的注释使用option + command + /快速生成Xcode默认格式注释
  • 实现文件中的注释使用//
  • 使用//注释时, 与注释内容间空一格
最近的文章

iOS提审详解

#[TOC]AppStore信息##App信息###可本地化的信息####名称 在AppStore中显示的名称 长度不能超过30个字符 名称   ####副标题 可选 在iOS11或更高系统版本的AppStore中的名称下方显示 长度不能超过30个字符 副标题   ####隐私政策网址(URL) 必须提供隐私政策网址 如无提供默认使用公司官网隐私...…

iOS开发继续阅读
更早的文章

iOS内购调研

内购调研 内购类型 官方文档说明   消耗型 非消耗型 自动续订型 非自动续订型 购买次数 多次 一次 多次 多次 票据号显示 ...…

iOS开发继续阅读