现在的位置: 首页 > 综合 > 正文

iOS应用开发最佳实践:编写高质量的Objective-C代码

2014年06月15日 ⁄ 综合 ⁄ 共 5853字 ⁄ 字号 评论关闭
点标记语法
属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法。
 
良好的风格
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
 
不良的风格
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
 
间距
二元运算符和参数之间需要放置一个空格,一元运算符、强制类型转换和参数之间不放置空格。关键字之后圆括号之前需要放置一个空格。

void *ptr = &value + 10 * 3;

NewType a = (NewType)b;

 

for (int
= 0; i < 10;
i
++)
{

    doCoolThings();

}

 

数组和字典类型的字面值的方括号两边各放置一个空格。

NSArray *theShit = @[
@1
, @2, @3
]
;

字典字面值的键和冒号之间没有空格,冒号和值之间有一个空格。
NSDictionary *keyedShit = @{ GHDidCreateStyleGuide: @YES };
 
C函数声明中,左括号的前面不保留空格,并且函数名应该像类一样带有命名空间标识。
 
良好的风格:
void RNCwesomeFunction(BOOL
hasSomeArgs);
 
长的字面值应被拆分为多行。
 
良好的风格:

NSArray *theShit = @[

    @"Got some long string objects in here.",

    [AndSomeModelObjects too],

    @"Moar strings."

];

 

NSDictionary *keyedShit = @{

    @"this.key": @"corresponds to this value",

    @"otherKey": @"remoteData.payload",

    @"some": @"more",

    @"JSON": @"keys",

    @"and": @"stuff",

};

每一行代码使用4个空格缩进。不使用tab缩进。下图是在Xcode的Preferences进行缩进设置的截图。
 
方法签名以及其他关键字(if/else/switch/while等)后面跟随的左花括号总是和语句出现于同一行,而右花括号独占一行。
 
良好的风格:

if (user.isHappy) {

//Do something

}

else {

//Do something else

}

如果一个方法内有多个功能区域,可以使用空行分隔功能区域。
 
每一行代码不要超过100个字符。
 
每一个方法之前都有一个99字符宽的注释行,注释行相对于使用空行更能提高代码的辨识度,当一行代码很长的时候,注释行也起到了越界检测的作用。注释行:
///////////////////////////////////////////////////////////////////////////////////////////////////
 
条件语句
所有的逻辑块必须使用花括号包围,即使条件体只需编写一行代码也必须使用花括号。
 
良好的风格做法:

if (!error) {

    return success;

}

不良的风格:

if (!error)

    return success;

或:
if (!error) return success;
 
三元运算符
长的三元运算符应使用圆括号括起来。三元运算符仅用于赋值和做参数。
Blah *a = (stuff == thing ? foo : bar);
 
合并的nil三元运算符应该尽量避免。
 
不良的风格:
Blah *b = thingThatCouldBeNil ?: defaultValue;
 
多分支条件应该使用if语句或重构为实例变量。
 
良好的风格:
result = a > b ? x : y;
 
不良的风格:
result = a > b ? x = c > d ? c : d : y;
 
异常和错误处理
不要在流控制语句中使用异常(NSException)。
 
异常仅用于表明程序员的错误。
 
为了表明一个错误,使用NSError *。
 
当一个方法通过引用返回一个错误参数,应该检测返回值的状态,而不是错误参数的状态。
 
良好的风格:

NSError *error;

if (![self trySomethingWithError:&error]) {

    // Handle Error

}

 
不良的风格:

NSError *error;

[self trySomethingWithError:&error];

if (error) {

    // Handle Error

}

 
在方法执行成功的情况下赋值非Null值给错误参数,会使路径跳转到假条件分支(随后程序奔溃)。
 
代理
除了继承一个类或实现一个协议,否则在头文件中仅使用类声明@class指令,不用#import导入类头文件。
 
如果一个delegate只有几个方法,比如只是提交和取消,推荐使用block编写动作响应代码。
 
由于代理方法的声明一般都很长,所以必须将代理对象和其他的协议对象放在实例变量定义的下面,否则实例变量定义的对齐方式将会被打乱掉。
 
当需要实现多个协议的时候,将每一个协议名拆分到单独的行。
 
良好的风格:

@interface CustomModelViewController : TTViewController <

  TTModelDelegate,

  TTURLRequestDelegate

> {

 
方法
一个方法的命名首先描述返回什么,接着是什么情况下被返回。方法签名中冒号的前面描述传入参数的类型。以下类方法和实例方法命名的格式语法:

[object/class thing+condition];

[object/class thing+input:input];

[object/class thing+identifer:input];

 
Cocoa命名举例:

realPath    = [path     stringByExpandingTildeInPath];

fullString  = [string   stringByAppendingString:@"Extra
Text"];

object      = [array    objectAtIndex:3];

// 类方法

newString   = [NSString stringWithFormat:@"%f",1.5];

newArray    = [NSArray  arrayWithObject:newString];

 
良好的自定义方法命名风格:

recipients  = [email    recipientsSortedByLastName];

newEmail    = [CDCEmail emailWithSubjectLine:@"Extra
Text"];

emails      = [mailbox  messagesReceivedAfterDate:yesterdayDate];

 
当需要获取对象值的另一种类型的时候,方法命名的格式语法如下:

[object adjective+thing];

[object adjective+thing+condition];

[object adjective+thing+input:input];

 
良好的自定义方法命名风格:

capitalized = [name    capitalizedString];

rate        = [number  floatValue];

newString   = [string  decomposedStringWithCanonicalMapping];

subarray    = [array   subarrayWithRange:segment];

 
方法签名尽量做到含义明确。
 
不良的风格:

-sortInfo  // 是返回排序结果还是给info做排序

-refreshTimer  // 返回一个用于刷新的定时器还是刷新定时器

-update  // 更新什么,如何更新

 
良好的风格:

-currentSortInfo      // "current" 清楚地修饰了名词SortInfo

-refreshDefaultTimer  // refresh是一个动词。

-updateMenuItemTitle  // 一个正在发生的动作

 
方法类型修饰符+/-后要放置一个空格,各参数名之间也要放置一个空格。
 
良好的风格:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
 
如果方法的命名特别长,将方法名拆分成多行。
 
良好的风格:

color = [NSColor colorWithCalibratedHue: 0.10

                               saturation: 0.82

                              brightness: 0.89

                                    alpha: 1.00];

 
不要将私有的实例变量和方法声明在头文件中,应将私有变量和方法声明在实现文件的类扩展内。

不良的风格:

//MyViewController.h文件

@interface MyViewController : UIViewController<

 UITalbeViewDataSource,

 UITableViewDelegate> {

 @private:

  UITableView *_myTableView;  // 私有实例变量

}

// 内部使用的属性

@property (nonatomic,strong) NSNumber *variableUsedInternally;

- (void)sortName;  // 只用于内部使用的方法

@end

良好的风格:

//MyViewController.m文件使用类扩展

@interface MyViewController()<

 UITalbeViewDataSource,

 UITableViewDelegate> {

  UITableView *_myTableView;

// 外部需要访问的实例变量声明为属性,不需要外部访问的声明为实例变量

  NSNumber * variableUsedInternally;

}

// Xcode4.3开始,可以不写方法的前置声明,Interface
Builder
Storyboard仍然可以找到方法的定义

@end

构造函数通常应该返回实例类型而不是id类型
 
参数
方法参数名前一般使用的前缀包括“the”、“an”、“new”。
 
良好的风格:

- (void)       setTitle:           (NSString *)   aTitle;

- (void)       setName:            (NSString *)   newName;

- (id)         keyForOption:       (CDCOption *)  anOption

- (NSArray *)  emailsForMailbox:   (CDCMailbox *) theMailbox;

- (CDCEmail *) emailForRecipients: (NSArray *)    theRecipients;

 
变量
变量的命令应尽量做到自描述。除了在for()循环语句中,单字母的变量应该避免使用(如i,j,k等)。一般循环语句的当前对象的命名前缀包括“one”、“a/an”。对于简单的单个对象使用“item”命名。
 
良好的风格:

for (i = 0; i < count; i++) {

    oneObject =
[allObjects objectAtIndex:
i];

    NSLog (@"oneObject: %@", oneObject);

}

      

NSEnumerator *e = [allObjects objectEnumerator];

id item;

while (item =
[e nextObject])

      NSLog (@"item: %@", item);

 
指针变量的星号指示符应该紧靠变量,比如NSString *text,而不是NSString* text或NSString * text。
 
尽量的使用属性而非实例变量。除了在初始化方法(init,initWithCoder:等)、dealloc方法以及自定义setter与getter方法中访问属性合成的实例变量,其他的情况使用属性进行访问。
 
良好的风格:

@interface RNCSection: NSObject

@property (nonatomic) NSString *headline;

@end

不良的风格:

@interface RNCSection : NSObject {

    NSString *headline;

}

 
当你使用@synthesize指令时,编译器会自动为你创建一个下划线_开头的的实例变量,所以不需要同时声明实例变量和属性。
 
不良的风格:

@interface RNCSection : NSObject {

    NSString *headline;

}

@property (nonatomic) NSString *headline;

@end

 
良好的风格:

@interface RNCSection: NSObject

@property (nonatomic) NSString *headline;

@end

 
不要使用@synthesize除非是编译器需要。注意在@protoco协议中的@optional可选属性必须被显式地使用@synthesize指令合成属性。
 
缩略词
虽然方法命名不应使用缩略词,然而有些缩略词在过去被反复的使用,所以使用这些缩略词能更好的的表达代码的含义。下表列出了Cocoa可接受的缩略词。
........................................................
以下是一些常用的首字母缩略词
 
ASCII
 
PDF
 
XML
 
HTML
 
URL
 
RTF
 
HTTP
 
TIFF
 
JPG
 
PNG
 
GIF
 
LZW
 
ROM
 
RGB
 
CMYK
 
MIDI
 
FTP
 
命名
方法和变量的命令应该尽可能做到自描述。
 

抱歉!评论已关闭.