命名
### 通用的约定
尽可能遵守 Apple 的命名约定,尤其是和 内存管理规则 (NARC) 相关的地方。
推荐使用长的、描述性的方法和变量名
推荐:
UIButton *settingsButton;
不推荐:
UIButton *setBut;
Constants 常量
常量应该使用驼峰命名法,并且为了清楚,应该用相关的类名作为前缀。
推荐:
static const NSTimeInterval ZOCSignInViewControllerFadeOutAnimationDuration = 0.4;
不推荐:
static const NSTimeInterval fadeOutTime = 0.4;
常量应该尽量使用 in-line 的字符串字面值或者数字,这样便于经常用到的时候复用,并且可以快速修改而不用查找和替换。 常量应该用 static 声明,并且不要使用 #define,除非它就是明确作为一个宏来用的。
推荐:
static NSString * const ZOCCacheControllerDidClearCacheNotification
= @"ZOCCacheControllerDidClearCacheNotification";
static const CGFloat ZOCImageThumbnailHeight = 50.0f;
不推荐:
#define CompanyName @"Apple Inc."
#define magicNumber 42
常量应该在 interface 文件中这样被声明:
extern NSString *const ZOCCacheControllerDidClearCacheNotification;
并且应该在实现文件中实现它的定义。
你只需要为公开的常量添加命名空间前缀。即使私有常量在实现文件中可能以不同的模式使用,你也不需要坚持这个规则了。
方法
对于方法签名,在方法类型 (-/+ 符号)后应该要有一个空格。方法段之间也应该有一个空格(来符合 Apple 的规范)。在参数名称之前总是应该有一个描述性的关键词。
使用“and”命名的时候应当更加谨慎。它不应该用作阐明有多个参数,比如下面的initWithWidth:height: 例子:
推荐:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
不推荐:
- (void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height; // Never do this.
字面值
NSString, NSDictionary, NSArray, 和 NSNumber 字面值应该用在任何创建不可变的实例对象。特别小心 nil 不能放进 NSArray 和 NSDictionary 里,这会导致 Crash。
例子:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" :
@"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
不要这样做:
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex",
@"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @
"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018];
对于那些可变的副本,我们推荐使用明确的如 NSMutableArray, NSMutableString 这些类。
下面的例子 应该被避免:
NSMutableArray *aMutableArray = [@[] mutableCopy];
上面的书写方式存在效率以及可读性的问题。
效率方面,一个不必要的不可变变量被创建,并且马上被废弃了;这并不会让你的 App 变得更慢(除非这个方法会被很频繁地调用),但是确实没必要为了少打几个字而这样做。
对于可读性来说,存在两个问题:
第一个是当浏览代码并且看见 @[] 的时候你的脑海里马上会联系到 NSArray 的实例,但是在这种情形下你需要停下来思考下。
另一个方面,一些新手看到后可能会对可变和不可变对象的分歧感到不舒服。他/她可能对创造一个可变对象的副本不是很熟悉(当然这并不是说这个知识不重要)。当然,这并不是说存在绝对的错误,只是可用性(包括可读性)有一些问题。