1、 UIGraphicsGetCurrentContext() /函数 NSCellDisabled /常量(d)避免给方法名加下划线前缀来表示为私有方法(给实例变量加下划线前缀来 表示私有变量是允许的)。苹果保留了此约定的使用。类名、协议名类名应当包含能清晰指出该类的功能的名词。 类名,类别名和协议名的首字母大写,使用首字母大写的形式分割单词在面向特定应用的代码中,类名应尽量避免使用前缀,每个类都使用相同 的前缀影响可读性。协议头文件里的协议名不要和类名混淆。 LoginDelegate /协议名,加上Delegate Login /不好。看上去像一个类名。 (e) 方法名方法的参数采用“驼峰
2、”命名法表示操作对象的方法,用动词开始命名。 - (void)invokeWithTarget:(id)target;多个参数时,每个参数使用参数标签 - (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag 正确(SEL)aSelector :(id)anObject :(BOOL)flag 错误方法名称要清晰的表达出方法的功能。 - (id)viewWithTag:(NSInteger)aTag;正确 - (id)taggedView:(int)aTag; 错误当创建一个比继承的方法参数更多的方法时,在
3、继承的方法后边添加新的关键字。 - (id)initWithFrame:(CGRect)frameRect; /UIView,NSView(CGRect)frameRect mode:(int)aMode numberOfRows:(int)rowsHigh / NSMatrix, a subclass numberOfColumns:(int)colsWide; / of NSView不要使用“and”来连接那些作为receiver属性的关键字。 - (int)runModalForDirectory:(NSString *)path file:(NSString *)name types:
4、(NSArray *)fileTypes; 正确; andFile: andTypes: 错误方法描述了两个分离的动作,用“and”连接它们; -(BOOL)opneFile:(NSString *)fulPath withApplication:(NSString *)appNameandDeactiovation:(BOOL)flag;方法名应简短清晰,但不能因简短牺牲清晰insertObject: atIndex: /好 insert:at: /不好,不够清晰;removeObjectAtIndex:/好removeObject: /好,因为它移除参数提及的对象; remove: /不清
5、晰,要移除什么?方法名应尽量全拼,即使单词很长。因为你写的缩写不一定是广为人知的,因为开发者有着各自的文化和语言背景。destinationSelection:destSel: /不好setBackgroundColor;setBkgdColor: /不好当然,少量的缩写是通常所见和使用了很长历史的可以排除在外。alloc,alt, app,calc, dealloc, func, horiz, info, init, int, max, min, msg, nib, pboard, rect, Rep, temp, vert等。还有计算机工业常用的,ASCII, PDF, XML, HTML
6、, URL, RTF, HTTP, TIFF, JPG, PNG, FIG, LZW, ROM, RGB, CMYK, MIDI, FTP等。API方法名避免有歧义,即能别理解一种以上的意思。sendPort: /不好,是发送端口号还是要返回一个端口号?如果不需要重写getter方法时,getter的方法名和变量名应相 同。不允许使用“get”前缀。 - (id) getDelegate; / 禁止- (id)delegate;/ 对头重写getter时可以使用,例如: property(getter=getFontSize)NSInteger fontSize;访问器方法根据属性名称:如果属
7、性为名词,格式为 - (type)noun; - (void)setNoun:(type)aNoun; 如果属性为形容词,格式为 - (BOOL)isAdjective; - (void)setAdjective:(BOOL)flag; 如果属性为动词,格式为 - (BOOL)verbObject; - (void)setVerbObject: 不要把动词用分词的形式转成形容词,例如: - (void)setAcceptsGlyphInfo: - (void)setGlyphInfoAccepted: 可以使用情态动词(can, should, will等)明确意思,但不能用do,does。
8、只有方法间接返回对象和值的时候使用“get”。只有在多个条目需要被返回的时候才能使用如下命名: - (void)getLineDash:(float*)pattern count:(int*)count phase:(float*)phase;不同类里做相同功能的方法应该有相同的方法名称,即一致性。前缀有规定的格式:包含两到三个大写字母,不能使用下划线或者 “sub prefixes”.标准如:NS,AB,IB等。在面向多应用的代码 中,推荐使用前缀。GTMSendMessage命名classes,protocols, functions,constants,typedef structure
9、s时使用前缀。命名 methods时不要使用前缀;方法是存在于定义它们 的类所创建的 namespace里。也不要在命名结构体字段时使用前缀。 如果你是一个大cocoa框架的子类,想绝对确定你的私有方法有一 个不同于其他子类的名字,你可以添加一个自己的前缀给私有方法。 这个前缀尽可能独一的,基于你的公司或工程的缩写格式 “XX_method”.本规则仅针对Objective-C代码,C+代码使用C+的编码习惯。2. 变量名变量名应使用容易意会的应用全称,命名使用“驼峰”表示法。二 格式化代码1. 指针”*”号的位置,“*”前加空格,紧跟参数名 如: UITextField *mTextFiel
10、d;2. 每行的长度每行的长度尽量在100个字符之内,保持美观大方。3. 方法的声明和定义(a) 在“-”或者“+”和返回值之间留1个空格,方法名和第一个参数间不留。- (void)doSomethingWithString:(NSString *)theString /dosomething (b) 当参数过长时,每个参数占用一行,以冒号对齐。- (void)doSomethingWith:(GTMFoo *)theFoo rect:(NSRect)theRect interval:(float)theInterval / dosomething (c) 如果方法名比参数名短,每个参数占用一
11、行,至少缩进4个字符,且为垂直 对齐(而非使用冒号对齐)。- (void)short: longKeyword: evenLongerKeyword: / dosomething5.方法的调用(a) 调用方法沿用声明方法的习惯。例外:如果给定源文件已经遵从某种习惯,继 续遵从那种习惯。(b) 所有参数应在同一行中,或者每个参数占用一行且使用冒号对齐。myObject doFooWith:arg1 name:arg2 error:arg3;或arg1 name:arg2 error:(c)和方法的声明一样,如果无法使用冒号对齐时,每个参数一行、缩进4个字符、垂直对其(而非使用冒号对齐)。myOb
12、j short:arg1 evenLongerKeyword:(d) public 和private public 和private使用单独一行,且缩进1个字符(e) Protocals类型标示符、代理名称、尖括号间不留空格。该规则同样适用于:类声明、实例变量和方法声明。interfaceMyProtocoledClass : NSObject private id delegate;- (void)setDelegate:(id)delegate;end三 Cocoa 和Objective-C特有的规则1.成员变量成员变量使用private。interfaceMyClass : NSObje
13、ct id myInstanceVariable;/ public accessors, setter takes ownership- (id)myInstanceVariable;- (void)setMyInstanceVariable:(id)theVar;2. Indentify Designated Initializer 一个精心设计的初始化方法应当完成以下步骤来确保适当的检测和误差传播。 通过调用super的指定初始器重新分配self; 检测返回值和nil对比,这可以指出一些发生在父类的初始器里的错误。如果初始化当前类时发生了一个错误,释放掉该类对象并返回nil。如下所示: -
14、 (id)init self = super init; /Call a designated initializer here; if (self != nil) / Initialize object . if (someError) self release; self = nil; return self; 2. 初始化 在初始化方法中,不要将变量初始化为“0”或“nil”,那是多余的 内存中所有的新创建的对象(isa除外)都是0,所以不需要重复初始化为 “0”或“nil”,避免显式的调用+new方法 禁止直接调用NSObject的类方法+new,也不要在子类中重载它。使用alloc和
15、 init方法4. #import VS #include 使用#import引入Ojbective-C和Ojbective-C+头文件,使用,#include引入C和C+头文件 import根框架(root frameworks),而非各单个文件 虽然有时我们仅需要框架(如Cocoa 或Foundation)的某几个头文件,但引入根文件编译器会运行的更快。因为根框架(rootframeworks),一般会预编译,所以加载会更快。再次强调:使用#import 而非#include 来引入Objective-C框架。#import #import .Foundation/Foundation.h
16、 /正确5. 创建对象时autorelease 与release 的使用 一般情况下不用的对象需要release,不建议使用autorelease,在release的时候要严格按照内存管理的方法进行。在以下两种情况下需要使用autorelease :(a) 方法返回指针类型的对象时需要用到autorelease - (NSMutableArray *)getBookmarkPreset /return object should autorelease NSMutableArray *bookMarkList = NSMutableArray alloc init autorelease; /
17、do something return bookMarkList;(b) 方法的逻辑判断比较复杂,有可能提前返回的情况下,建议使用autorelease,虽然这样会稍微有点慢,但这样可以阻止因为提前return 或其他意外情况导致的内存泄露。 MyController* controller = MyController alloc init autorelease; / . 这里的代码可能会提前return .controller release;6. 先release,再retain 在为对象赋值时,遵从“先release,再retain” 在将一个新创建的对象赋给变量时,要先将旧对象re
18、lease掉,否则会内 存泄露。- (void)setFoo:(GMFoo *)aFoo foo_ release; foo_ = aFoo retain; dealloc的顺序要与变量声明的顺序相同,这有利于review代码 NSString的属性的setter使用“copy” ,禁止使用retain,以防止意外的修改了NSString变量的值。 - (void)setFoo:(NSString *)aFoo foo_ autorelease; foo_ = aFoo copy; 或 property (nonatomic, copy) NSString *aString;7. 对nil 的
19、检查 仅在有业务逻辑需求时检查nil,而非为了防止崩溃8. BOOL陷阱将int值转换为BOOL时应特别小心。避免直接和YES比较Objective-C中,BOOL被定义为unsigned char,这意味着除了YES(1) 和 NO(0)外它还可以是其他值。禁止将int直接转换为BOOL。常见的错误包括:将数组的大小、指针值或位运算符的结果转换为 BOOL,因为该BOOL值的结果取决于整型值的最后一 位将整型值转换为BOOL的方法:使用三元运算符返回YES / NO,或使用 位运算符(&,|,!) BOOL、_Bool和bool之间的转换是安全的,但是BOOL和 Boolean间的转换不是安
20、全的,所以将Boolean看成整型值。在Objective-C中,只允许使用BOOL,如: / 禁止 - (BOOL)isBold return self fontTraits &NSFontBoldTrait; /&得出来的值是int不是Bool,避免出现返回int。 - (BOOL)isValid return self stringValue; / 对头 - (BOOL)isBold return (self fontTraits &NSFontBoldTrait) ? YES : NO; - (BOOL)isValid return self stringValue != nil; -
21、 (BOOL)isEnabled return self isValid & self isBold; 禁止直接将BOOL和YES/NO比较,如: / 禁止 BOOL great = foo isGreat; if (great = YES) . / 对头 BOOL great = foo isGreat; if (great) 9. 属性 通过使用声明property和synthesize组合来避免显式声明公共实例变 量。如果要显式声明一个实例变量,要么private或者protected。如果该 类派生子类,子类需要访问该类数据,使用protected。 位置:属性的声明紧随成员变量块之后
22、,中间空一行,无缩进。 严把权限:对不需要外部修改的属性使用readonly NSString使用copy而非retain。 一般使用nonatomic,除非特殊情况下使用atomic ,例如多线程。四Cocoa Pattern(模式)1. Delegate Pattern(委托模式)delegate对象使用assign,禁止使用retain。因为retain会导致循环索引导 致内存泄露, 并且此类型的内存泄露无法被Instrument发现,极难调试2. Model/View/Controller Model和View分离。 不要在与view相关的类中添加过多的业务逻辑代码,这让代码的可重用性
23、很差 。 Controller负责业务逻辑代码,且Controller的代码与view尽量无关 使用protocal定义回调APIs,如果并非所有方法都是必须的,可选使用 optional标示,必选使用 required标识.五 其他1. init方法和deallocinit和dealloc方法是是最常用的方法,所以将他们放在类实现的开始位置(a) 使用空格将相同的变量、属性对齐,使用换行分组(b) 在设定视图frame时,会随屏幕大小变化的视图使用controller.view.frame 的相对数值。/MyViewController.m-(void)viewDidLoad supervi
24、ewDidLoad;/ Do something .UIScrollView *mScrollView = UIScrollViewalloc initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);self.viewaddSubview:mScrollView;2. 多view视图排版有多个view同时在一个view上时,其之间的间距用变量来设定; /MyViewController.m superviewDidLoad; int i = 0; UILabel *l1 = UILabelalloc initWithFrame:CGRectMake(0, i, 100, 30);self.view addSubview:l1;l1 release;i+=50;UILabel *l2 = UILabelalloc initWithFrame:l2;l2 release;i+=60;UILabel *l3 = UILabelalloc initWithFrame:l3;l3 release;3. 开发中尽可能使用代码,xib尽少使用。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1