Objective-C 编码规范(三,四)
目录
3 注释
3.1 声明部分的注释
【建议】每个接口、类别以及协议应辅以注释,以描述它的目的及与整个项目的关系。
// A delegate for NSApplication to handle notifications about app
// launch and shutdown. Owned by the main app controller.
@interface MyAppDelegate : NSObject {
...
}
@end
如果你已经在文件头部详细描述了接口,可以直接说明 “完整的描述请参见文件头部”,但是一定要有这部分注释。
另外,公共接口的每个方法,都应该有注释来解释它的作用、参数、返回值以及其它影响。
为类的线程安全性作注释,如果有的话。如果类的实例可以被多个线程访问,记得注释多线程条件下的使用规则。
3.2 实现部分的注释
【建议】使用 | 来引用注释中的变量名及符号名而不是使用引号。
这会避免二义性,尤其是当符号是一个常用词汇,这使用语句读起来很糟糕。例如,对于符号 count :
// Sometimes we need |count| to be less than zero.
或者当引用已经包含引号的符号:
// Remember to call |StringWithoutSpaces("foo bar baz")|
注:不过中文注释的话可以忽略该条
3.3 对象所有权
【建议】当与 Objective-C 最常规的作法不同时,尽量使指针的所有权模型尽量明确。
继承自 NSObject 的对象的实例变量指针,通常被假定是强引用关系(retained),某些情况下也可以注释为弱引用(weak)或使用 __weak 生命周期限定符。同样,声明的属性如果没有被类 retained,必须指定是弱引用或赋予 @property 属性。然而,Mac 软件中标记上 IBOutlets 的实例变量,被认为是不会被类 retained 的。
当实例变量指向 CoreFoundation、C++ 或者其它非 Objective-C 对象时,不论指针是否会被 retained,都需要使用 __strong 和 __weak 类型修饰符明确指明。CoreFoundation 和其它非 Objective-C 对象指针需要显式的内存管理,即便使用了自动引用计数或垃圾回收机制。当不允许使用 __weak 类型修饰符(比如,使用 clang 编译时的 C++ 成员变量),应使用注释替代说明。
@interface MyDelegate : NSObject {
@private IBOutlet NSButton *okButton_; // normal NSControl; implicitly weak on Mac only
AnObjcObject* doohickey_; // my doohickey
__weak MyObjcParent *parent_; // so we can send msgs back (owns me) // non-NSObject pointers...
__strong CWackyCPPClass *wacky_; // some cross-platform object
__strong CFDictionaryRef *dict_;
}
@property(strong, nonatomic) NSString *doohickey;
@property(weak, nonatomic) NSString *parent;
@end
3.4 方法声明注释
【建议】声明的方法,要注释方法功能,参数意义,返回值,格式如下:
//含参数,有返回值的方法注释
/**
* 初始化方法-2
* @param frame frame
* @param array 标题数组
* @param index 默认选中标题索引
* @return WJSegmentView
*/
- (instancetype)initWithFrame:(CGRect)frame
titleArray:(NSArray *)array
sellectIndex:(long)index;
//无参,无返回值方法注释
/**移除键盘*/
+ (void)removeKeyBoard{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *window in windows){
[CommonMethods textViewTextFieldResignFirstResponder:window];
}
}
3.5 属性的注释
【建议】在声明文件中声明的实例变量在上一行加注释。或者直接在实例变量后边注释,与项目已有风格保持一致。
格式如下:
@property (nonatomic,copy)NSString *loginID;//登录ID
@property (nonatomic,copy)NSString *userName;//用户名
@property (nonatomic,copy)NSString *realName;//真是姓名
@property (nonatomic,copy)NSString *shareUrl;//二维码分享链接
@property (nonatomic,copy)NSString *appShareUrl;//社交分享链接
@property (nonatomic,copy)NSString *headPortraitAddr;//用户头像
/**标题数组*/
@property (nonatomic,retain)NSArray *titleArray;
/**选中按钮底部背景*/
@property (nonatomic,retain)UIView *backgroundView;
/**默认选中索引*/
@property (nonatomic,assign)long selectIndex;
4 代码组织
4.1 条件语句
当使用条件语句编码时,左手边的代码应该是”golden” 或 “happy”路径。也就是不要嵌套if语句,多个返回语句也是OK。
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
【建议】出现超过两层循环的代码,用函数或block替代
// 为了简化示例,没有错误处理,并使用了伪代码
// 糟糕的例子
- (Task *)creatTaskWithPath:(NSString *)path {
Task *aTask;
if ([path isURL]) {
if ([fileManager isWritableFileAtPath:path]) {
if (![taskManager hasTaskWithPath:path]) {
aTask = [[Task alloc] initWithPath:path];
}
else {
return nil;
}
}
else {
return nil;
}
}
else {
return nil;
}
return aTask;
}
// 改写的例子
- (Task *)creatTaskWithPath:(NSString *)path {
if (![path isURL]) {
return nil;
}
if (![fileManager isWritableFileAtPath:path]) {
return nil;
}
if ([taskManager hasTaskWithPath:path]) {
return nil;
}
Task *aTask = [[Task alloc] initWithPath:path];
return aTask;
}
4.2 实现文件目录结构
【建议】 在函数分组和protocol/delegate实现中使用#pragma mark -来分类方法,要遵循以下一般结构:
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - NSObject
- (NSString *)description {}