1、闭包(Blocks)
-
block内的代码采用4个空格的缩进。
-
^和(之间,^和{之间都没有空格,参数列表的右括号)和{之间有一个空格。
//分行书写的block,内部使用4空格缩进 [operation setCompletionBlock:^{ [weakSelf.delegate newDataAvailable]; }]; //使用C语言API调用的block遵循同样的书写规则 dispatch_async(_fileIOQueue, ^{ NSString* path = [weakSelf sessionFilePath]; if (path) { // ... } });
2、使用前缀
功能拆分,组件化开发,打包成FrameWork等,使用命名前缀是非常有用的。
项目TARGETS名称(大写缩写2个字符)+ 功能模块(首字母大写)+ 功能实现子类 + 类型后缀
3、命名方法(Methods)
方法的参数命名也有一些需要注意的地方:
1. 不要使用只有一两个字母的参数名;
2. 不要使用简写,拼出完整的单词;
//正确,保证每个参数都有关键词修饰 - (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag;
4、命名属性和实例变量(Properties&Instance Variables)
命名实例变量,在变量名前加下划线 (有些有历史的代码会将_放在后面),其它和命名属性一样:
@implementation MyClass { BOOL _showsTitle; UIButton *flashActionBtn_; //咱的开发项目统一用下划线_放在后面; }
5、命名常量(Constants)
[必须] 声明常量请使用const类型声明,禁止使用#define宏定义;
使用const定义浮点型或者单个的整数型常量,如果要定义一组相关的整数常量,应该优先使用枚举。常量的命名规范和函数相同:
正例:
// 局部可见 const CGFloat kAnimationDuration = 2.0; // 全局可见 const CGFloat UIActivityIndicatorViewAnimationDuration = 2.0;
6、 命名通知(Notifications)
通知常用于在模块间传递消息,所以通知要尽可能地表示出发生的事件,通知的命名范式是:
[触发通知的类名] + [Did | Will] + [动作] + Notification
如:
UIKeyboardWillShowNotification UIApplicationWillEnterForegroundNotification NSApplicationDidBecomeActiveNotification NSColorPanelColorDidChangeNotification
7、图片命名如:
[项目简写字母]_[文件名]_[功能简写]
xs_invite_view_cancel@2x.png lh_pk_view_begin@2x.png
8、类名
[必须] 类名命名风格由"前缀+类的名称+类的类型"3个部分组成;
前缀若等于2个字符可以考虑添加_。
//秀色为例: XS_LoginViewController LH_LoginViewController XSLoginViewController
XS_表示前缀,Login表示该类跟登录相关,ViewController表示该类是一个视图控制器而不是View。
9、方法命名规范
-
[必须] 所有方法名称禁止以new开始。
[必须] 所有方法名称禁止使用_开始。
-
方法内局部临时变量命名可以加上标识符作为前缀
//正例: t_label、t_string //(t在这里表示temp,也可以是其他p,项目中保持一致)
10、常用建议
-
头文件中尽量不要声明成员变量而是使用属性代替 ;
-
头文件中尽量少引用其他头文件,尽量使用@class向前声明,每次引入其他头文件时问问自己是否必须要这样做;
-
UI控件建议使用weak修饰而不是strong修饰。
那么我们在开发中,到底是用weak还是用strong?
1、如果你真的怕麻烦,也不想理解什么内存管理,你就用strong就对了。
2、可以分情况来看,如果你用strong修饰了属性,并且也addSubview:了,虽然引用计数为2,但是当整个父视图被销毁的时候,这两个引用计数都会变成0,所以不会造成内存泄漏。
3、使用strong:只有当前父视图被销毁的时候,指向selfStrongView的强引用才会取消,selfStrongView才会被销毁,所以这种情况下,即便是removeFromSuperView,还是无法释放该控件!只能强行手动设置:selfStrongView = nil;所以个人建议:还是使用weak连接控件,只要我们在创建控件的时候,在当前的作用域 { xxx }中,添加到父视图上,就能为其添加强引用保证它不被销毁。然后当我们removeFromSuperView的时候,可以实现控件的销毁!
{ @property (nonatomic,weak) GuguSelRankTabView *selfWeakView; @property (nonatomic,strong) GuguSelRankTabView *selfStrongView; } { [self.selfStrongView removeFromSuperview]; // selfStrongView 没有被销毁 不走dealloc self.selfStrongView = nil; // 需要手动设置 nil 才能被销毁 走dealloc [self.selfWeakView removeFromSuperview]; // selfWeakView 被销毁 会走dealloc }
11、代码注释
-
类方法 和 .h 文件的方法和属性 ,要求必须写注释。
快捷键 command + option + / 备注: /** */ 为iOS老版本,/// 为新提倡注释,项目新开发中提倡///注释。
单个文件 属性 和 方法注释最好要统一, 都用/// 或者 /** */ ;
/// 是否是主播 @property (nonatomic, assign) BOOL isMaster; /// 是否隐藏H5 @property (nonatomic, assign) BOOL isHideH5url; /// 在连麦中 @property (nonatomic, assign) BOOL isAudioAgroaIng; /// 在语音房麦位上 @property (nonatomic, assign) BOOL isAudioRoomSeat; /// 语音房开播 @property (nonatomic, assign) BOOL isAudioRoomLive;
/** * 类方法,用来显示直播间 * * @param roomId 房间号 * @param fromType =0 老版本,默认值=1 大厅及各TAB =2 上滑=3 下滑=4 大跑道=5 push消息 =6 个人空间=7 活动页面=8 排行榜=9 下播推荐=10 用户接受主播连麦邀请=11 推荐主播列表 * @param liveshowCoverUrl 封面url * @param navigationController 导航控制器 * @param liveshowType 直播间类型:回放和直播 * @param playbackId 回放id */ /// 类方法,用来显示直播间 /// @param roomId 房间号 /// @param fromType =0 老版本,默认值=1 大厅及各TAB =2 上滑=3 下滑=4 大跑道=5 push消息 =6 个人空间=7 活动页面=8 排行榜=9 下播推荐=10 用户接受主播连麦邀请=11 推荐主播列表 /// @param liveshowCoverUrl 封面url /// @param navigationController 导航控制器 /// @param liveshowType 直播间类型:回放和直播 /// @param playbackId 回放id + (void)pushToYJLiveShowViewController:(NSInteger)roomId fromType:(NSInteger)fromType liveshowCoverUrl:(NSString *)liveshowCoverUrl navigationController:(UINavigationController *)navigationController liveshowType:(BeeLiveshowType)liveshowType playbackId:(NSInteger)playbackId;
12、编码规范
1、不要使用new方法。
2、不要将BOOL类型变量直接和YES比较:
//错误,无法确定|great|的值是否是YES(1),不要将BOOL值直接与YES比较 BOOL great = [foo isGreat]; if (great == YES) // ...be great! //正确 BOOL great = [foo isGreat]; if (great) // ...be great!
3、[必须] 在dealloc方法内禁止将self传递出去,如果self被retain,到下个runloop周期再释放则会多次释放导致crash。
- (void)dealloc { [_bar release]; [super dealloc]; } // 错误禁止使用 - (void)dealloc { self.bar = nil; [super dealloc]; }
4、NSString非常常用,在它被传递或者赋值时应当保证是以复制(copy)的方式进行的,这样可以防止在不知情的情况下String的值被其它对象修改。
- (void)setFoo:(NSString *)aFoo { _foo = [aFoo copy]; }
@interface ViewController() @property(nonatomic, copy) NSString *str1; @property(nonatomic, strong) NSString *str2; @end -(void)test{ NSMutableString*str=[NSMutableStringstringWithFormat:@"helloworld"]; self.str1=str; self.str2=str; NSLog(@"str:%p--%p",str,&str); NSLog(@"copy_str:%p--%p",_str1,&_str1); //str1指针地址和str 不一样 创建新的地址 NSLog(@"strong_str:%p--%p",_str2,&_str2); //str2指针地址和str 一样 强引用 [str appendString:@"hry"]; NSLog(@"****************%@",self.str1); // 打印结果 helloworld NSLog(@"****************%@",self.str2); // 打印结果 helloworldhry }
5、Delegate要使用弱引用
/**delegate**/ @property (nonatomic, weak) id <IPCConnectHandlerDelegate> delegate;
6、必须使用CGRectGet获取Frame的各种值,而不是通过frame.的方式获取
CGRect t_frame = CGRectMake(-10, -10, -10, -10);
//正例: CGRectGetWidth(frame)、CGRectGetMinX(frame)、CGRectGetMaxX(frame) //反例: frame.size.width、frame.origin.x、frame.size.width + frame.origin.x
7、工程规范
-
局部使用的常量、静态变量声明在@interface之前;
-
@property同一类型的声明放在一块,不同类型的声明用一行空格隔开;
-
#pragma mark - LifeCycle(生命周期相关的代码放在最上面)
- (id)init{} - (void)viewDidLoad {} - (void)viewWillAppear:(BOOL)animated {} ... - (void)dealloc {} #pragma mark - Public(公开方法) // code... // 上空一行 // 下空两行 #pragma mark - Private(私有方法) ... #pragma mark - Override(需要覆盖父类的方法) ... #pragma mark - Notification(通知方法) ... #pragma mark - Delegate(Delegate需要实现的方法) ... #pragma mark - getter/setter ..