IOS编码规范

IOS开发规范

公司新项目马上要启动,整理一篇规范,供参考。

命名规范

驼峰法,除第一个单词之外,其他单词首字母大写。

属性命名

描述性的单词+变量类型,一目了然,如:

@property(nonatomic,weak)IBOutlet UILabel *titleLabel;

@property(nonatomic,weak)IBOutlet UILabel *dateLabel;

类命名

普通功能也面类命名规范,功能模块前缀+类型/模型/管理,一目了然,如:

MessageTableViewCell.h

MessageTableViewCell.m

MessageTableViewCell.xib

MessageTableViewController.h

MessageTableViewController.m

MessageTableViewController.xib

ProductViewController.h

ProductViewController.m

ProductViewController.xib

ProductItem.h

ProductItem.m

ProductModel.h

ProductModel.m

UserManager.h

UserManager.m

NetworkManager.h

NetworkManager.m

方法命名

一个规范的方法读起来应该像一句完整的话,读过之后便知函数的作用。

执行性的方法应该以动词开头,小写字母开头。

返回性的方法应该以返回的内容开头,但之前不要加get。如:

-(void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;

-(instancetype)arrayWithArray:(NSArray *)array;

-(ProductModel *)productWithCategory:(NSString *)categoryId;

常量命名

对于常量的命名前面加上字母k作为标记. 如:

static const NSTimeInterval kAnimationDuration = 0.3;

定义作为NSDictionary或者Notification等的Key值字符串时加上const关键字, 以防止被修改. 如:

NSString *const UIApplicationDidEnterBackgroundNotification

枚举命名

对于枚举类型, 经常会看到之前的C的定义方式:

typedef enum : {
    CameraModeFront,
    CameraModeLeft,
    CameraModeRight,
} CameraMode;

作为一个iOS开发要以Objective-C的方式来定义:

typedef NS_ENUM (NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
};

这边需要注意的是: 枚举类型命名要加相关类名前缀并且枚举值命名要加枚举类型前缀.

图片命名

原则:

1)采用单词全拼,或者大家公认无岐义的缩写(比如:nav,bg,btn等)

2)采用“模块_功能”命名法,模块分为公共模块、私有模块。公共模块主要包括统一的背
景、导航条、标签、按钮背景、图标、默认图等等;私有模块主要根据app的业务
功能模块划分,比如用户中心,消息中心等。

公共模块命名示例:

导航条背影图片:bg_nav_bar@2x.png

导航返回按钮正常:nav_back_normal@2x.png

导航返回按钮选中:nav_back_selected@2x.png

标签item背景正常:tabbar_record_normal@2x.png

标签item背景选中:bg_tabbar_record_selected@2x.png

私有模块命名示例:

首页搜索背景图:home_search@2x.png

首页消息默认背景图:home_info_normal@2x.png

首页消息高亮背景图:home_info_highlight@2x.png

注释规范

属性注释

使用/** 注释 */的方式,这种方式在引用时Xcode会给出友好提示。

@interface UserItem : BaseModel

/** ID */
@property(nonatomic,assign) NSInteger itemId;

/** 用户名 */
@property(nonatomic,strong) NSString *name;

/** 密码 */
@property(nonatomic,strong) NSString *password;

/** 手机号 */
@property(nonatomic,strong) NSString *phoneNum;

/** 头像 */
@property(nonatomic,strong) NSString *headerPic;

/** 关注人ID */
@property(nonatomic,assign) NSInteger attentionId;

/** 热度 */
@property(nonatomic,assign) NSInteger hotScore;

/** 推荐状态 */
@property(nonatomic,assign) NSInteger commendState;

@end

方法注释

严格采用苹果官方提供的注释标准,这种方式在引用时Xcode会给出友好提示。

/**
 对AF进行简单封装
 */
@interface SSNetworkingManager : AFHTTPSessionManager

/**
 单利方法
 @return 实例
 */
+(instancetype _Nonnull )shareManager;

/**
 *  封装的GET请求
 *
 *  @param URLString  请求的链接
 *  @param parameters 请求的参数
 *  @param success    请求成功回调
 *  @param failure    请求失败回调
 */
- (void)SSGET:(NSString *)URLString parameters:(NSDictionary *)parameters success:(Success)success failure:(Failure)failure;

/**
 *  封装的POST请求
 *
 *  @param URLString  请求的链接
 *  @param parameters 请求的参数
 *  @param success    请求成功回调
 *  @param failure    请求失败回调
 */
- (void)SSPOST:(NSString *)URLString parameters:(NSDictionary *)parameters success:(Success)success failure:(Failure)failure;

/**
 *  封装POST图片上传(多张图片) // 可扩展成多个别的数据上传如:mp3等
 *
 *  @param URLString  请求的链接
 *  @param parameters 请求的参数
 *  @param picArray   存放图片模型(HDPicModle)的数组
 *  @param progress   进度的回调
 *  @param success    发送成功的回调
 *  @param failure    发送失败的回调
 */
- (void)SSPOST:(NSString *)URLString parameters:(NSDictionary *)parameters andPicArray:(NSArray *)picArray progress:(Progress)progress success:(Success)success failure:(Failure)failure;

/**
 *  封装POST图片上传(单张图片) // 可扩展成单个别的数据上传如:mp3等
 *
 *  @param URLString  请求的链接
 *  @param parameters 请求的参数
 *  @param picModle   上传的图片模型
 *  @param progress   进度的回调
 *  @param success    发送成功的回调
 *  @param failure    发送失败的回调
 */
- (void)SSPOST:(NSString *)URLString parameters:(NSDictionary *)parameters andPic:(SSImageModel *)picModle progress:(Progress)progress success:(Success)success failure:(Failure)failure;

/**
 *  封装POST上传url资源
 *
 *  @param URLString  请求的链接
 *  @param parameters 请求的参数
 *  @param picModle   上传的图片模型(资源的url地址)
 *  @param progress   进度的回调
 *  @param success    发送成功的回调
 *  @param failure    发送失败的回调
 */
- (void)SSPOST:(NSString *)URLString parameters:(NSDictionary *)parameters andPicUrl:(SSImageModel *)picModle progress:(Progress)progress success:(Success)success failure:(Failure)failure;

/**
 *  下载
 *
 *  @param URLString       请求的链接
 *  @param progress        进度的回调
 *  @param destination     返回URL的回调
 *  @param downLoadSuccess 发送成功的回调
 *  @param failure         发送失败的回调
 */
- (NSURLSessionDownloadTask *)SSdownLoadWithURL:(NSString *)URLString progress:(Progress)progress destination:(Destination)destination downLoadSuccess:(DownLoadSuccess)downLoadSuccess failure:(Failure)failure;

@end

#pragma mark

视图方法中必须添加mark标记,方便查找文件中的具体方法和理解整个类的结构。

 #pragma mark - Lifecycle

-(id)init{}

 - (void)dealloc {}

 - (void)viewDidLoad {}

 - (void)viewWillAppear:(BOOL)animated {}

 - (void)didReceiveMemoryWarning {}

 #pragma mark - Lazy

  - (void)setUpTableView{}

 #pragma mark - IBAction

 - (IBAction)submitData:(id)sender {}

 #pragma mark - Common

 - (void)publicMethod {}

 - (void)privateMethod {}

 #pragma mark - UITextFieldDelegate

 #pragma mark - UITableViewDataSource

 #pragma mark - UITableViewDelegate
 

编码规范

判断nil或者YES/NO

Preferred:

if (someObject) { ... } 
if (!someObject) { ... }

Not preferred:

if (someObject == YES) { ...} 
if (someObject != nil) { ...}

if (someObject == YES)容易误写成赋值语句, 自己给自己挖坑了...而且if (someObject)写法很简洁.

条件赋值

Preferred:

result = object ? : [self createObject];

Not preferred:

result = object ? object : [self createObject];

如果是存在就赋值本身, 那就可以这样简写.

初始化方法

Preferred:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;

使用字面量,保证代码更加简洁。

定义属性

Preferred:

@property(nonatomic,assign) NSInteger itemId;
@property(nonatomic,strong) NSString *name;

BOOL赋值

Preferred:

BOOL isAdult = age > 18;

Not preferred:

BOOL isAdult;
if (age > 18)
{
    isAdult = YES;
}
else
{
    isAdult = NO;
}

拒绝写死值

Preferred:

if (car == Car.Nissan) ...

const int adultAge = 18; 
if (age > adultAge) {
 ... 
}

Not preferred:

if (carName == "Nissan") ...

if (age > 18) { 
 ... 
}

死值每次修改的时候容易被遗忘, 地方多了找起来就悲剧了。而且定义成枚举或者static可以让错误发生在编译阶段。

复杂的条件判断

Preferred:

if ([self canDeleteJob:job]) { ... }        

- (BOOL)canDeleteJob:(Job *)job {
    BOOL invalidJobState = job.JobState == JobState.New
                          || job.JobState == JobState.Submitted
                          || job.JobState == JobState.Expired;
    BOOL invalidJob = job.JobTitle && job.JobTitle.length;

    return invalidJobState || invalidJob;
}

Not preferred:

if (job.JobState == JobState.New
    || job.JobState == JobState.Submitted
    || job.JobState == JobState.Expired
    || (job.JobTitle && job.JobTitle.length)) {
 ... 
}

专门的方法做专门的事情。

嵌套判断

Preferred:

if (!user.UserName) return NO;
if (!user.Password) return NO;
if (!user.Email) return NO;

return YES;

Not preferred:

BOOL isValid = NO;
if (user.UserName) {
    if (user.Password) {
        if (user.Email) isValid = YES;
    }
}
return isValid;

黄金路径

参数过多

Preferred:

- (void)registerUser(User *user) {
 ...
}

Not preferred:

- (void)registerUserName:(NSString *)userName
                password:(NSString *)password 
                   email:(NSString *)email {
 ...
}

当发现实现某一功能需要传递的参数太多时, 就预示着你应该聚合成一个model类了...这样代码更整洁, 也不容易因为参数太多导致出错。

回调方法

Preferred:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

函数调用的可知性, 回调时被调用者要知道其调用者, 方便信息的传递, 所以建议在回调方法中第一个参数中加上调用者

本文参考:
//www.greatytc.com/p/da8a471219d1
//www.greatytc.com/p/414bb5a53139

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • 注释规范 文件头注释 文件头注释采用如下格式,该注释由xcode自动生成。如果你对其他人的原始代码作出重大的修改,...
    yangzming阅读 724评论 0 1
  • 命名 Bundle id命名: 规则:采用反域名命名规则,全部使用小写字母。一级包名为com,二级包名根据应用进行...
    Tippi阅读 1,620评论 0 2
  • 一、文件目录 项目基本目录结构如下,针对项目不同,可略作差异处理: 1.Views 存放界面层UIViewCont...
    可齐阅读 458评论 2 2
  • Object-C 开发代码规范概要Object-C是一门面向对象的动态编程语言,主要用于编写IOS和MAC应用程序...
    克鲁德李阅读 530评论 0 1
  • 【奢毒】 一截断肠埋在烟台上发芽 束秋的稻梗悬挂成古木桠 那混杂清荷雨拍打的乐章 跟飘开去的星光一样奢华 在目光穿...
    清风陌然阅读 847评论 0 1