运算符
- 一元运算符与变量之间没有空格
!bValue
~iValue
++iCount
*strSource
&fSum
- 二元运算符与变量之间必须有空格
fWidth = 5 + 5;
fLength = fWidth * 2;
fHeight = fWidth + fLength;
for(int i = 0; i < 10; i++)
变量
1.变量名必须使用驼峰格式,自定义类,协议使用大驼峰
SFHomePageViewController
2.对象等局部变量使用小驼峰
NSString *personName = @"";
3.变量的名称必须同时包含功能与类型
UIButton *addButton //添加按钮
UILabel *nameLabel //名字标签
NSArray *nameArray //名字数组
NSDictionary *productDict //产品字典
常量
1.常量以相关类名作为前缀
static const NSTimeInterval YZDLoginAnimateViewFadeOutTime = 0.4;
2.对外公开某个常量,如通知
//.h文件
extern NSString *const YZDLoginOutNotification;
//.m文件
static NSString * const YZDLoginOutNotification = @"YZDLoginOutNotification";
枚举
- 使用NS_ENUM进行定义
- 对于一些状态 选项的使用枚举
尽量少用根据数字判断状态少用字符串 数字判断状态
typedef NS_ENUM(NSInteger, DQGameInfoDisplayType) {
DQGameInfoDisplayTypeDefault = 0,
DQGameInfoDisplayTypeMatch = 1, //比赛
DQGameInfoDisplayTypeEvent = 2, //对应节目
};
宏
- 宏、常量名都要使用大写字母,用下划线‘_’分割单词
#define URL_GAIN_QUOTE_LIST @"/v1/quote/list"
#define URL_UPDATE_QUOTE_LIST @"/v1/quote/update"
#define URL_LOGIN @"/v1/user/login”
- 宏定义中如果包含表达式或变量,表达式和变量必须用小括号括起来
#define MY_MIN(A, B) ((A)>(B)?(B):(A))
- 开头用k标识,比如Cell的重用字符,k+cell的名称+identifier
#define kGBHomeItemTableViewCellIdentifier = @"kGBHomeItemTableViewCellIdentifier"
属性
- 属性的关键字推荐按照原子性,读写,内存管理的顺序排列
@property (nonatomic, readwrite, copy) NSString *name;
@property (nonatomic, readwrite, strong) UIView *headerView;
方法
- 方法名中不应使用and,而且签名要与对应的参数名保持高度一致
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
- 方法实现时,如果参数过长,则令每个参数占用一行,以冒号对齐
- (void)doSomethingWithFoo:(NSString *)theFoo
rect:(CGRect)theRect
interval:(CGFloat)theInterval {
//Implementation
}
- 大括号开始与行尾
void function(param1,param2) {
}
类
- 类文件名要见名知意
- Model类名以Model结尾
YZDUserModel
- 自定义视图命名以View结尾
YZDTabIndexHeaderView
- 视图控制器命名以ViewController结尾
YZDTabIndexViewController
- init && dealloc
// 将 dealloc 方法放在实现文件的最前面
- (void)dealloc {
// 释放注册的通知和KVO的监听
}
- (instancetype)init {
self = [super init]; // call the designated initializer
if (self) {
// Custom initialization
}
return self;
}
- 类的头文件中尽量少引用其他头文件
有时,类A需要将类B的实例变量作为它公共API的属性。这个时候,我们不应该引入类B的头文件,而应该使用向前声明(forward declaring)使用class关键字,并且在A的实现文件引用B的头文件。,这么做的优点:
- 不在A的头文件中引入B的头文件,就不会一并引入B的全部内容,这样就减少了编译时间。
- 可以避免循环引用:因为如果两个类在自己的头文件中都引入了对方的头文件,那么就会导致其中一个类无法被正确编译。
// EOCPerson.h
#import
@class EOCEmployer;
@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) EOCEmployer *employer;//将EOCEmployer作为属性
@end
// EOCPerson.m
#import "EOCEmployer.h"
但是个别的时候,必须在头文件中引入其他类的头文件:
主要有两种情况:
- 该类继承于某个类,则应该引入父类的头文件。
- 该类遵从某个协议,则应该引入该协议的头文件。而且最好将协议单独放在一个头文件中
- 头文件.h
- 方法的参数在一排显示
- 方法之间保留一行
- 第一个方法和property保留空行
- 最后一个方法和@end保留空行
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, copy) NSString *name;
- (void)testName;
- (void)testAge;
@end
- 实现文件.m
- 引用头文件的顺序
#import <AVFoundation/AVFoundation.h>
#import <Mantle/Mantle.h>
#import "SFUserStatus.h"
- 类的布局顺序
- (void)dealloc
#pragma mark - Life Cycle Methods
#pragma mark - Override Methods
#pragma mark - Network Methods
#pragma mark - Target Methods
#pragma mark - Public Methods
#pragma mark - Private Methods
#pragma mark - Delegate
#pragma mark - Lazy Loads
分类
- 分类添加的方法需要添加前缀和下划线
@interface NSMutableDictionary (DQSafetyCheck)
/**
* 空值保护 key,value为空时防止crash
*
* @param anObject object
* @param aKey key
*/
- (void)dq_setSafeObject:(id)anObject forKey:(id)aKey;
@end
if语句
- 必须列出所有分支(穷举所有的情况),而且每个分支都必须给出明确的结果。推荐这样写
var hintStr;
if (count < 3) {
hintStr = "Good";
} else {
hintStr = "";
}
不推荐这样写
var hintStr;
if (count < 3) {
hintStr = "Good";
}
- 不要使用过多的分支,要善于使用return来提前返回错误的情况
推荐这样写:
- (void)someMethod {
if (!goodCondition) {
return;
}
//Do something
}
不推荐这样写:
- (void)someMethod {
if (goodCondition) {
//Do something
}
}
- 条件过多,过长的时候应该换行
if (condition1() &&
condition2() &&
condition3() &&
condition4()) {
// Do something
}
Switch语句
- 每个分支都必须用大括号括起来,每个case都要添加break关键字,避免出现fall-through
switch (integer) {
case 1: {
// ...
break;
}
case 2: {
// ...
break;
}
case 3: {
// ...
break;
}
default: {
// ...
break;
}
}
- 使用枚举类型时,不能有default分支, 除了使用枚举类型以外,都必须有default分支
RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;
switch (menuType) {
case RWTLeftMenuTopItemMain: {
// ...
break;
}
case RWTLeftMenuTopItemShows: {
// ...
break;
}
case RWTLeftMenuTopItemSchedule: {
// ...
break;
}
}
函数
- 一个函数的长度不要太长
- 一个函数只做一件事(单一原则)
- 对于有返回值的函数(方法),每一个分支都必须有返回值
int function() {
if (condition1) {
return count1
} else if (condition2) {
return count2
} else {
return defaultCount
}
}
- 对输入参数的正确性和有效性进行检查,参数错误立即返回
void function(param1,param2) {
if (param1 is unavailable) {
return;
}
if (param2 is unavailable) {
return;
}
//Do some right thing
}
代理、block
- 代理,合理的使用optional,required关键字
- 向代理、block发送消息时需要判断其是否实现该方法
if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) {
[self.delegate signUpViewControllerDidPressSignUpButton:self];
}
字符串、数组、字典
取值一定要注意类型、非空、越界等的判断,防止崩溃等问题
- 字符串
//判断字符串是否是字符串,是否是null,一般从网络获取
static inline BOOL verifiedString(id strlike) {
if (strlike && ![strlike isEqual:[NSNull null]] && [[strlike class] isSubclassOfClass:[NSString class]] && ((NSString *) strlike).length > 0) {
return YES;
} else {
return NO;
}
}
// 用法
if (verifiedString(urlString)) {
// dosomething
}
- 数组
//判断是否是有效数组,一般从网络获取
static inline BOOL verifiedNSArray(id arraylike) {
if (arraylike && ![arraylike isEqual:[NSNull null]] && [[arraylike class] isSubclassOfClass:[NSArray class]] && [arraylike count] > 0) {
return YES;
} else {
return NO;
}
}
// 用法:数组类型 && 未越界
if (verifiedNSArray(self.dataArray) && indexPath.row < self.dataArray.count) {
}
- 字典
// 判断是否是字典,一般从网络获取
static inline BOOL verifiedNSDictionary(id dictlike) {
if (dictlike && ![dictlike isEqual:[NSNull null]] && [[dictlike class] isSubclassOfClass:[NSDictionary class]]) {
return YES;
} else {
return NO;
}
}
// 用法:数据的解析
if (verifiedNSDictionary(responseObject)) {
}
注释
优秀的代码大部分是可以自描述的,我们完全可以用程代码本身来表达它到底在干什么,而不需要注释的辅助。
但并不是说一定不能写注释,有以下四种情况比较适合写注释:
公共接口(注释要告诉阅读代码的人,当前类能实现什么功能)。
涉及到比较深层专业知识的代码(注释要体现出实现原理和思想)。
容易产生歧义的代码(但是严格来说,容易让人产生歧义的代码是不允许存在的)。
踩过坑的代码(如特定机型系统会崩溃之类的代码,如有解决方案或链接附上最佳)。
- Class注释
/**
Gif集锦,中间Gif视图
*/
@interface DQGifCollectionGifView : UIView
@end
- property注释
@interface DeliveryModel : NSObject
/// 提货劵所在商圈id
@property (nonatomic, assign) long long mallId;
/// 商圈全称
@property (nonatomic, copy) NSString *mallFullName;
/// 商圈简称
@property (nonatomic, copy) NSString *mallShortName;
/// 提货劵号
@property (nonatomic, copy) NSString *credentialsCode;
/// 总金额
@property (nonatomic, assign) NSInteger totalAmount;
- 方法注释
/**
* 圈子列表(达人榜/置顶/贴子列表)
*
* @param urlStr 请求URLStr
* @param params 参数
* @param block 返回的结果和code
*/
- (void)getCircleRefreshHeadListWithUrl:(NSString *)urlStr params:(NSDictionary *)params resultBackBlock:(DQAnalyzeBackBlock)block;
参考文献
网友评论