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的业务
功能模块划分,比如用户中心,消息中心等。

公共模块命名示例:

导航条背影图片:[email protected]

导航返回按钮正常:[email protected]

导航返回按钮选中:[email protected]

标签item背景正常:[email protected]

标签item背景选中:[email protected]

私有模块命名示例:

首页搜索背景图:[email protected]

首页消息默认背景图:[email protected]

首页消息高亮背景图:[email protected]

注释规范

属性注释

使用/** 注释 */的方式,这种方式在引用时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;

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

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

你可能感兴趣的:(IOS编码规范)