1.只使用空格,每次缩进两个空格。将你的文本编辑器设置成自动将制表符替换成空格。
2.行宽120
3.方法声明和定义/方法调用
- (void)doSomethingWithString:(NSString*)theString
{
...
}
如果一行有非常多的参数,将每个参数单独拆成一行。将每个参数前的冒号对齐。
-(void)doSomethingWith:(GTMFoo*)theFoo
rect:(NSRect)theRect
interval:(float)theInterval {...
}
当第一个关键字比其它的短时,保证下一行至少有4个空格的缩进。这样可以使关键字垂直对齐。
4. @public与@private
@interfaceMyClass : NSObject {
@public
...
@private
...
}
@end
总结:@public以及@private访问标识符应该以一个空格缩进。
5.异常
@try {
foo();
}
@catch (NSException*ex) {
bar(ex);
}
@finally {
baz();
}
每个@标签应该有独立的一行,在@与{}之间需要有一个空格。@catch与被捕捉到的异常对象的声明之间也要有一个空格。
6.协议
尖括号所包括的协议名称与前面的类型标识之间不应该有空格。
7.命名
编码风格取决于方法/函数以哪种语言实现。如果在一@implementation语句 块中,就使用Objective-C的风格。如果实现一个C++的类,请使用C++的风格。
8.类别名
类别中的方法 应该以gtm_myCategoryMethodOnAString为前缀以避免命名冲突,因为Objective-C只有一个命名空 间。
类名与包含类别名的括号之间,应该以一个空格分隔。
总结:类别名应该有两三个字母的前缀以表示类别是项目的一部分或者该类别是通用的。类别应该包含它所扩展的类的名字。
9.方法名
方法名应该读起来就像句子,这表示你应该选择与方法名连在一起读起来通顺的参数名。(例如,
convertPoint:fromRect:or replaceCharactersInRange:withString:)
每个命名的参数也应该以小写字母开头。
10.变量名
变量名应该以小写字母开头,并混合大小写。myLocalVariable
类的成员变量应该以下划线作为后缀。myInstanceVariable_。
常量名(如宏、枚举、静态局部变量等)应该以小写字母k开头,使用混合大小写的格式来分隔单词,如:kInvalidHandle。
11.注释
1⃣以版权信息和作者作为文件头部,开始每一个文件,后接文件内容的描述。如果你对其他人的原始代码作出重大的修改,请把你的名字添加到作者里面。
2⃣️每个接口、类别以及协议应该注释,以描述它的目的及作用。
3⃣️公共接口的每个方法,都应该有注释来解释它的作用、参数、返回值以及其它影响。
使用|来引用注释中的变量名及符号名而不是使用引号。
// Sometimeswe need |count| to be less than zero.
// Remember tocall |StringWithoutSpaces("foo bar baz")|
Cocoa以及Objective-C特性
1. 成员变量应该声明为私有。
2. 注释并且明确指出你的类的指定的初始化器。
3. 当你写子类的时候,如果需要init...方法,记得重写父类的指定的初始化器。
4. 刚分配的对象,默认值都是0。除了isa指针(注:NSObject的isa指针,用于标识对象的类型)。所以不要在初始化器里面写一堆将成员初始化为0或者nil的代码。
5. #importOjbective-C/Objective-C++头文件,#include C/C++头文件。
6. 当创建临时对象时,在同一行使用autolease,而不是在同一个方法的后面语句中使用一个单独的release。
7. 给对象赋值时遵守autorelease之后retain的模式。
- (void)setFoo:(GMFoo *)aFoo {
[foo_ autorelease]; // Won't dealloc if |foo_| == |aFoo| foo_ = [aFoo retain];
}
8. dealloc中对象被释放的顺序应该与他们在@interface中声明的顺序一致。
9. 接受NSString作为参数的setter,应该copy它所接受的字符串。
- (void)setFoo:(NSString *)aFoo {
[foo_ autorelease];
foo_ = [aFoo copy];
}
10. 不要抛出Objective-C异常,但准备从第三方的调用或者系统调用捕捉异常。Try-catch-finally
11. nil检查只用于逻辑流的判断。
12. 将常规整形转换成BOOL时要小心,不要直接将BOOL值与YES进行比较。当转换整形至BOOL时,使用三目操作符来返回YES或者NO。对BOOL使用逻辑运算符(&&, || 和!)是合法的。
13. 属性
1⃣️命名
属性所关联的成员变量的命名必须遵守以下划线作为后缀的规则。属性的名字应该与成员变量去掉下划线后缀的名字一模一样。使用@synthesize指示符来正确地重命名属性
@interface MyClass :NSObject {
@private
NSString *name_;
}
@property(copy, nonatomic)NSString *name;
@end
@implementation MyClass
@synthesize name =name_;
@end
2⃣️位置
类接口中的属性的声明必须紧跟着成员变量语句块。属性的定义必须在@implementation的类定义的最上方。他们的缩进与包含他们的@interface以及@implementation语句一样。
@interface MyClass :NSObject {
@private
NSString *name_;
}
@property(copy,nonatomic) NSString *name;
@end
@implementation MyClass
@synthesize name =name_;
- (id)init { ... }
@end
3⃣️NSString使用copy特性
NSString属性应该永远被声明为copy特性。这从逻辑上遵守了NSString的setter必须使用copy而不是retain。不要synthesize CFType的属性,CFType应该永远使用@dynamic实现指示符。
尽管CFT ype不能使用retain属性特性,开发者必须自己处理retain和release。很少有情况你需要仅仅 对它进行赋值,因此最好显示地实现getter和setter,并作出注释说明。
列出所有的实现指示符尽管@dynamic是默认的,显示列出它以及其它的实现指示符会提高可读性,代码阅读者可以一眼就知道类的每个属性是如何实现的。
4⃣️原子性
一定要注意属性的开销。所有synthesize的setter和getter都是原子的。这会给每个get或者set带来一定的同步开销。显示将你的属性声明为nonatomic除非你需要原子操作。
委托模式
实现委托模式的类应该:拥有一个名为delegate_的成员变量来引用委托。 因此,访问器方法应该名为delegate和setDelegate:。 delegate_对象不应该被retained。