跳过正文

ios团队代码规范

·6 分钟
目录

概述
#

Objective-C语言主要用于iOS和Mac开发,本文结合苹果规范和Google规范,再加上自己的个人经验总结出来的一系列编码规范。 苹果开发规范 apple object-c guide Google Objective-C规范google-objc-styleguide

代码缩进以及行代码
#

Apple是以4个空格缩进,所以Xcode里面我们这样设置。关于每行代码最大长度我们选用100个字符作为最大长度限制。编写的代码长度不可以大于这个最大值。

头文件引入
#

  1. 当引入Objective-C或者Objective-C++头文件的时候使用#import引入,当引入C或者C++头文件的时候使用#include引入
  2. 引入系统API时应该直接引用这个根头文件,而不是其它子模块的头文件,即使是你只用到了其中的一小部分,编译器会自动完成优化的。每一个框架都会有一个和框架同名的头文件,它包含了框架内接口的所有引用。正确做法#import <UIKit/UIKit.h> 错误做法 #import <UIKit/UIButton.h>
  3. 引入系统的API时使用#import <>格式
  4. 引入第三方框架优先使用#import <>格式
  5. 引入自己定义的类使用#import ““格式
  6. 将 import和其他的文件名之间加一个空格。如果有一个以上的 import 语句,就对这些语句进行分组。每个分组的注释是可选的。

注:对于模块使用 #import语法。除了子类化或是协议之外,最好使用 @class 这种方式,避免过多的头文件引入。在引入协议的时候,如果不是连当前类也引入的情况下,将协议单独声明出来再引入。

命名规范
#

所有的命名必须是英文规范,命名应该尽量的清晰。 尽量以描述性的方式来命名。命名需要自达意(即看到命名,即可清楚知道代表的意义)。

一致性
#

整个工程的命名风格要保持一致性,最好和苹果 SDK 的代码保持统一。不同类中完成相似功能的方法应该叫一样的名字,比如我们总是用 count 来返回集合的个数,不能在 A 类中使用 count 而在 B 类中使用 getNumber。

前缀
#

Apple规定:Apple保留所有两个字母前缀的使用权,因此为了防止与官方API冲突,项目中所有文件的前缀必须是三个(及以上)大写字母。 可以在为类、协议、函数、常量以及 typedef 宏命名的时候使用前缀,但注意不要为成员变量或者方法使用前缀,因为他们本身就包含在类的命名空间内。

xcode 可以对所有的类添加前缀。

Class命名规范
#

class的名称应该由两部分组成,前缀+名称。即,class的名称应该包含一个前缀和一个名词。

Protocol命名规范
#

  1. 有时候protocol只是声明了一堆相关方法,并不关联class。这种不关联class的protocol使用ing形式以和class区分开来。比如NSLocking而非NSLock。
  2. 如果proctocol不仅声明了一堆相关方法,还关联了某个class。这种关联class的protocol的命名取决于关联的class,然后再后面再加上protocol或delegate用于显示的声明这是一份协议。

代理方法命名规范
#

当特定的事件发生时,对象会触发它注册的代理方法。代理是 Objective-C 中常用的传递消息的方式。代理有它固定的命名范式。

一个代理方法的第一个参数是触发它的对象,第一个关键词是触发对象的类名,除非代理方法只有一个名为 sender 的参数:。

常量命名规范
#

不要使用 #define 宏来定义常量, #define 通常用来给编译器决定是否编译某块代码。 使用 const 定义基本数据类型或字符串常量,常量的命名规范和函数相同,但是常量一般用k。

通知命名规范
#

通知常用于在模块间传递消息,所以通知要尽可能地表示出发生的事件,通知的命名范式是

代码示例
#
//[ 触发通知的类名 ] + [Did | Will] + [ 动作 ] + Notification 例如:
NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification
NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification

编码规范
#

文件夹,层级结构的规范

代码组织规范
#

分块组织,如控制器页面生命周期方法放在一起,代理方法放在一起,属性相关方法放在一起。私有方法放在一起。内存管理的方法放在一起。

工程结构规范
#

  1. 为了避免文件杂乱,物理文件应该保持和 Xcode 项目文件同步。Xcode 创建的任何组(group)都必须在文件系统有相应的映射。为了更清晰,代码不仅应该按照类型进行分组,也可以根据业务功能进行分组。建议 遵循先业务group,后mvc group。

  2. 合理组织工程的内的文件夹,工程中一般包括但不限于以下几个文件夹Supporting Files(全局资源文件以及引入文件)、Library(第三方),Base(基类)。

    通知使用规范
    #

  3. 当我们使用通知时,必须要思考,有没有更好的办法来代替这个通知。禁止遇到问题就想到通知,把通知作为备选项而非首选项。

分支语句规范
#

  1. if条件判断语句后面必须要加大括号{}。不然随着业务的发展和代码迭代,极有可能引起逻辑问题。

  2. 多于3个逻辑表达式必须用参数分割成多个有意义的bool变量。

    bool的规范
    #

    Objective-C使用YES和NO。因为true和false应该只在CoreFoundation,C或C++代码使用。既然nil解析成NO,所以没有必要在条件语句比较。不要拿某样东西直接与YES比较。

CGRect函数规范
#

当访问CGRect里的x, y, width, 或 height时,应该使用CGGeometry函数而不是直接通过结构体来访问。引用Apple的CGGeometry:

在这个参考文档中所有的函数,接受CGRect结构体作为输入,在计算它们结果时隐式地标准化这些rectangles。因此,你的应用程序应该避免直接访问和修改保存在CGRect数据结构中的数据。相反,使用这些函数来操纵rectangles和获取它们的特性。

CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);

多线程规范
#

  1. 对剪贴板的读取必须要放在异步线程处理,最新Mac和iOS里的剪贴板共享功能会导致有可能需要读取大量的内容,导致读取线程被长时间阻塞。
  2. 仅当必须保证顺序执行时才使用dispatch_sync,否则容易出现死锁,应避免使用,可使用dispatch_async禁止在非主线程中进行UI元素的操作。
  3. 在主线程中禁止进行同步网络资源读取,使用NSURLSession进行异步获取。当然,你可以在子线程同步获取网络资源,但还是上面的那一条建议:避免使用dispatch_sync,尽量使用dispatch_async。因为死锁不一定只发生在主线程。
2.1 code
#
- (void)viewDidLoad {
   [super viewDidLoad];
   // 错误。出现死锁,报错:EXC_BAD_INSTRUCTION。原因:在主队列中同步的添加一个block到主队列中
   dispatch_queue_t mainQueue = dispatch_get_main_queue();
   dispatch_block_t block = ^() {
       NSLog(@"%@", [NSThread currentThread]);
   };
   dispatch_sync(mainQueue, block);
}

其他
#

不要在对象类型前和 protocol之间添加空格。 推荐使用方式

// 推荐:
@property (nonatomic, weak) id<OKDelegate> delegate;