图片 8

Cocoa编码指南,编码标准

By admin in 澳门新葡亰官网app on 2019年8月20日

 

注:本文转载自http://www.cocoachina.com/ios/20150908/13335.html,
非作者原创,用于个人随时查阅,特此声明!!!
简介:
本文整理自Apple文档《Coding Guidelines for
Cocoa》。这份文档原意是给Cocoa框架、插件及公共API开发者提供一些编码指导,实质上相当于Apple内部的编码规范。在多人协作时,一份统一的代码规范大大减少开发者之间的沟通成本,极力推荐。
目录:
一、代码命名基础
二、方法
三、函数
四、Property及其他
五、缩写
一、代码命名基础
1.通用原则
1.1 清晰
尽量清晰又简洁,无法两全时清晰更重要

翻译自“Coding Guidelines for Cocoa”

Cocoa编码规范

图片 1

使用公开的API开发一个Cocoa框架,插件,或者其它可执行文件需要的方法和规范,跟开发应用程序的不一样。产品的主要用户是开发者,他们不会被编程接口迷惑。此时API的命名规范就派上了用场,它们让接口保持清晰和一致性。同时它们也是编程技术,尤其对框架,例如版本控制,二进制兼容性,错误处理和内存管理。这个专题同时包括Cocoa命名规范和推荐的框架编程实践。

–前言

用公共API开发一个Cocoa框架,插件,或其他可执行目标,里面的命名编写和规范不同于一般应用程序的开发。因为你开发出来东西是给开发者用的看的,并且他们不熟悉你的编程接口。这个时候API的命名约定就派上用场了,因为它使你的写的接口清楚明确。本文档里还包括开发框架中一些特殊的/重要的编程技术,例如:版本控制,二进制兼容性,错误处理,和内存管理。本文档包含俩部分内容:Cocoa命名规范、一些框架的编程实践。

1441509819955470.png

本专题的文章分为两类。第一类是编程接口的命名规范。这些规范与Apple自己的Cocoa框架一样。下面是命名规范的文章:代码命名基础方法命名函数命名属性和数据类型命名可接受的缩写和首字母缩写

–文档组织

本文档内容分类俩大部分:第一部分是主要内容,为编程接口的命名规范。这些规范(有一些小的例外)也是Apple开发自己框架所用的规范。这些命名规范具体体现在以下几个方面:“基本代码命名”、“方法命名”、“函数命名”、“属性和数据类型命名”、“通用的缩写和简称”。
第二块部分讨论框架编程方面:“使用框架中的一些技巧和技术”。
注:本文章只翻译前一部分内容,即:Cocoa命名规范
=========================================章节分割线=========================================

通常不应缩写名称,即使方法名很长也应完整拼写
你可能认为某个缩写众所周知,但其实未必,特别是你周围的开发者语言文化背景不同时

第二部分讨论框架编程相关的规范。框架开发者的技巧和技术

–基本命名规则

在面对对象软件库开发中,一个经常被忽视的问题是:类、方法、函数、常数等编程接口的命名问题。这一章主要讨论Cocoa接口中常用代码的命名规范。

有一些历史悠久的缩写还是可以使用的,详见第五章

设计面向对象软件库时,类,协议,方法,函数,常量,以及其它元素的命名经常被忽略。这一节讨论大部分Cocoa接口的命名规范。

–一般规则

图片 2

清晰

–明确

代码越简洁越明确越好,但是不能因为简洁而导致语义不明确:

代码 评价
insertObject: atIndex:
insert:at: 不明确,什么被插入?at指什么
removeObjectAtIndex:
removeObject: 好,没有之前讨论的那些问题
remove: 不明确,什么被移除了

通常,不要缩写对象的名称。即使它们很长,也全拼:

代码 评价
destinationSelection
destSel 不明确
setBackgroundColor:
setBkgdColor: 不明确

–你可能认为某些缩写是众所周知的。但凡是无绝对,尤其是当开发者和你文化、语言背景不一样,看这些缩写就可能产生歧义。

 

–当然,一些公认的通用的缩写,还是可以用。参考“通用的缩写”章节

在API的命名上避免歧义,例如方法的名字可以有多个解释:

code 评价
sendPort 是发送端口还是返回端口
displayName 它是显示一个名字还是在用户界面返回消息发送者的标题

 

1441509896749042.png

  • 尽可能同时保持清晰和简洁,但不要因为简洁而牺牲清晰:
–一致性

始终使用Cocoa
编程接口的名字。如果你不太确定,查看已有的头文件和参考文档。

一致性非常重要,当你有个实现多态方法的类。不同类中处理同一个任务的方法应该拥有同样的名称。

code 评价
– (NSInteger)tag 在 NSView, NSCell, NSControl类中都要定义

 

API命名避免歧义,例如一个方法名有多种理解

代码 点评
insertObject:atIndex:
insert:at: 不清晰;插入什么?“at”表示什么?
removeObjectAtIndex:
removeObject: 好,因为参数指定了要移除的对象
remove 不清晰;要移除什么?
–不要自我引用(Self Reference)

命名不应该自我重复。

code 评价
NSString okay
NSStringObject 自我引用

常数(看做标记,可以进行位运算)不适用这个规则,例如用作通知名称。

code 评价
NSUnderlineByWordMask okay
NSTableViewColumnDidMoveNotification okay

图片 3

  • 通常不要使用名字的缩写。即使名字很长,也要拼写完全:
–前缀

前缀在编程接口中是非常重要的一部分。一个软件有不同的功能模块,通常它们封装在一个框架或者相近的框架中。前缀避免了第三方开发者和Apple之间的命名冲突。
–前缀有规定的格式。通常由2/3个大写字母组成,不是用下划线和子前缀。例如:NS、IB、AB。
–使用前缀来命名类、协议、函数、常数,自定义数据类型(typedef
structures),不要用前缀来命名方法。方法存在类的命名区域中,不要在这区域里面使用前缀。

1441509905881130.png

代码 点评
destinationSelection
destSel 不清晰
setBackgroundColor:
setBkgdColor: 不清晰
–书写规则

对于由多个单词组成的名字,不要使用标点符号(下划线、破折号等)作为名称部分或作为分隔符。相反每个单词第一个字母大写并且连着写–骆驼风格。注意一下几点:
–对于方法名字,小写字母开头,不要用前缀。一个例外是,方法名称以通用的缩写开头,例如:TIFFRepresentation
(NSImage)。
–对于函数和常数,和相关类使用相同的前缀,并且大写第一个字母。例:NSRunAlertPanel、NSCellDisabled。
–避免使用下划线作为前缀意义在于会导致方法名称私有的意思(可以用它做实例变量)。Apple保留使用该规则。但在第三方用可能导致命名冲突,他们会不自觉的重写自己已有的一个私有方法。参考“私有方法”章节。

1.2 一致
尽力保持Cocoa编程接口命名一致
如果有疑惑,请浏览当前头文件或者参考文档

你可能会认为某个缩写广为人知,但可能并非如此,尤其是当方法或函数名被不同文化和语言背景的开发人员使用时。

–类和协议名称

一个类的名称应该包含一个名词,清楚地表明的类(或类的对象)作用或者意义。名称应该有一个适当的前缀(参考“前缀”小节)。在框架中类名的例子比比皆是:NSString,NSDate,nsscanner,NSApplication,UIApplication,NSButton,
and UIButton。
协议的命名应该根据使用协议的相应类行为命名。
–大多数协议包含的相关方法,不与任何特定的类关联。这种协议的应该命名为使协议与类不能混淆。一个通常的规则是用动名词(…ing)。对比NSLocking
、NSLock(看起来像类名)。
–有的协议包含一些没什么联系的方法(而不是创建多个独立的小协议)。这些协议跟一个类的联系很大,这个类主要体现了这个协议。这种情况下,命名规则为协议名跟类名字一样。一个例子是NSObject
协议,这个协议包含一些方法可以查询任何类在父类中的层次位置等。因为NSObject类实现了协议的大部分方法,所以协议可以以类名命名。

当某个类的方法使用了多态时,一致性尤其重要
不同类里,功能相同的方法命名也应相同

  • 可以使用少数非常常见和历史悠久的缩写。参考“可接受的缩写和首字母缩写”一节。

  • 避免使用有歧义的API名称,例如有多个解释的方法名。

–头文件

怎么命名你的头文件非常重要。因为你的命名表明了类中的内容:
声明一个独立的类/协议:如果一个类/协议不是一个文件中的一部分,将其声明独立成一个文件,这个文件的名字表明了该类/协议;
声明联系的类/协议:如果有一些联系的声明(类、协议、分类),将它们声明放到一个文件中,文件的命名根据基础的类、协议、分类;

头文件 声明
NSString.h NSString和NSSMutableString
NSLock.h NSLocking协议、NSLock、NSConditionLock、NSRecursive类

-包含框架的头文件:所有的框架都有一个头文件,以框架命名,包含框架里所有公开的头文件。例Foundation.h–
Foundation.framwork。
–为别的框架中类增加API:如果你在一个框架中声明的方法,是另一个框架中类的分类,名字为原来类的名字拼接上“Additions”。一个例子为Applicatiion
kit 的NSBuddleAdditions.h头文件。
–相联系的函数和数据类型:如果你有一些相联系的函数、常数、结构体等其他数据类型,将它们放到合适命名的头文件中。例如NSGraphics.h(Applicatiion
kit )。
=========================================章节分割线=========================================

图片 4

代码 点评
sendPort 发送端口还是返回一个发送端口?
displayName 显示名称还是返回用户界面中接收者的标题?

–方法命名

方法在编程接口中非常常见,所以命名方法要重视。这章主要讨论方法命名的以下几个方面:

1441509959926816.png

一致性

–基本规则

当为方法命名时,要记住以下几点:
—-方法名小写开头,之后每个单词首字母大写(Camel-Case),不要用前缀;
有俩种情况例外。如果方法用到了众所周知的缩写(例如TIFF或PDF)
;你可能使用前缀去统一定义私有方法,参考“私有方法”小节。
—-如果方法代表对象某个动作,方法名用动词开头; 例如:-
(void)invokeWithTarget:(id)target;
不要使用do或does这样的词做名字一部分,因为这些辅助动词没什么意义,同时不要在动词前使用副词或形容词。
—–如果方法返回的是消息发送者(对象)的属性,用属性命名方法。get这个词不需要,除非有多个间接返回的值。可以参考“存取器方法”小节。

– (NSSize)cellSize; 正确
– (NSSize)calcCellSize; 错误
– (NSSize)getCellSize; 错误

—-在所有的参数前使用关键词

– (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag; 正确
– (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; 错误

—-参数前的单词描述参数的意义

– (id)viewWithTag:(NSInteger)aTag; 正确
– (id)taggedView:(int)aTag; 错误

—–当你创建一个基于现有方法的新方法,在一个已有的方法上添加关键词

– (id)initWithFrame:(CGRect)frameRect; UIView
– (id)initWithFrame:(NSRect)frameRect mode:(int)aMode cellClass:(Class)factoryId numberOfRows:(int)rowsHigh numberOfColumns:(int)colsWide; NSMatrix, a subclass of
NSView

—-不要使用and去连接多个参数的关键词(对象属性名)

– (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; right
– (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; wrong

尽管在这个例子中and看起来还不错,但是当方法中有许多参数的时候,再用and就不行了。
—-如果方法包含着俩个分开的动作,用and去连接它们;例:-
(BOOL)openFile:(NSString *)fullPath withApplication:(NSString
*)appName andDeactivate:(BOOL)flag;

1.3 避免自引用(self Reference)
命名不应自引用
这里的自引用指的是在词尾引用自身

  • 尽可能使用与Cocoa编程接口一致的名称。如果不确定某个命名,请浏览当前的头文件或参考文件中的范例。

  • 当类的方法使用多态时,一致性尤其重要。不同类中实现相同功能的方法应该有相同的名称。

–存取器方法

存取器放方法是指那些读/写对象属性的方法,根据属性意义的不同,它们有不同的通用格式。(备注:不同格式代表不同对应实例变量的写法,存取器方法形式就是intanceVariables
和 setIntanceVariables俩种形式)
—-如果属性表示的是名词意思,格式如:– (type)noun; –
(void)setNoun:(type)aNoun;

—-如果属性表示的是形容词意思,格式如:– (BOOL)isAdjective; –
(void)setAdjective:(BOOL)flag; (注意type是BOOL)
例:-
(BOOL)isEditable; – (void)setEditable:(BOOL)flag;
—-如果属性表示的是动词意思 , 格式如:(BOOL)verbObject; –
(void)setVerbObject:(BOOL)flag; (注意type为BOOL)

例:– (BOOL)showsAlpha; – (void)setShowsAlpha:(BOOL)flag;
动词是现在时;
—-在属性的名称中,不要通过用分词形式将动词转换为形容词;

– (void)setAcceptsGlyphInfo:(BOOL)flag; right
– (BOOL)acceptsGlyphInfo; right
– (void)setGlyphInfoAccepted:(BOOL)flag; wrong
– (BOOL)glyphInfoAccepted; wrong

—-可以使用情态动词(动词前面“can”、“should”、“will”等)进一步说明属性意思,但不要使用’do’或’does’。

– (void)setCanHide:(BOOL)flag; Y
– (BOOL)canHide; Y
– (void)setShouldCloseDocument:(BOOL)flag; Y
– (BOOL)shouldCloseDocument; Y
– (void)setDoesAcceptGlyphInfo:(BOOL)flag; N
– (BOOL)doesAcceptGlyphInfo; N

—-当使用get这个词时,只有当方法间接返回多个对象/值。-
(void)getLineDash:(float *)pattern count:(int *)count phase:(float
*)phase;
注意,这种形式的方法,其中的引用型参数应该能接收NULL,因为方法调用者可能并不需要多个返回值。

图片 5

代码 点评
– (NSInteger)tag NSView, NSCell, NSControl中有定义
*- setStringValue:(NSString ) 在许多Cocoa类中有定义
–代理方法

代理方法是那些当发生特定事件对象使用它delegate调用的方法(如果delegate实现了它),它们有着特定的格式,这些格式也适用于对象的datesource方法。
—-名字的开头指明发消息的对象类型。例如:-
(BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row; –
(BOOL)application:(NSApplication *)sender openFile:(NSString
*)filename; 类名省略了它的前缀并且小写开头。
—-如果方法只有一个参数,格式为:冒号+类名(调用代理的对象)+sender;例:-
(BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
—-一个例外是方法用来发送通知,如果这样的话,方法参数为通知对象;例:-
(void)windowDidChangeScreen:(NSNotification *)notification;
—–命名中使用did或will这类词,告诉delegate某些事情已经发生或将要发生;例:-
(void)browserDidScroll:(NSBrowser *)sender;
—-虽然你可以在命名中是使用did或will这类词,告诉delegate去做某些事情,但有时“should”更合适;例:-
(BOOL)windowShouldClose:(id)sender;

1441509975783777.png

参考“方法参数”一节。

–集合方法(Collection Method)

要管理对象(每一个叫做对象的元素)的集合,命名方法以下格式: **-
(void)addElement:(elementType)anObj;

  • (void)removeElement:(elementType)anObj;
  • (NSArray *)elements;*
    例如: – (void)addLayoutManager:(NSLayoutManager \
    )obj;
  • (void)removeLayoutManager:(NSLayoutManager *)obj;
  • (NSArray *)layoutManagers; 以下是一些重要、有用的的规格:
    –如果集合没有顺序,返回NSSet比NSArray更好;
    –如果在集合中插入元素,位置很重要的话,使用以下的格式比前面提到的更好
    例如: – (void)insertLayoutManager:(NSLayoutManager *)obj
    atIndex:(int)index; – (void)removeLayoutManagerAtIndex:(int)index;
    以下一些实现细节要注意:
    —-这些方法通常暗含插入对象的拥有权(ownership)的管理,所以添加/插入元素的时候retain它们,移除的时候remove它们;
    —-如果插入对象想保持它原来的持有的对象,通常对该对象的setter方法不用retain,例如insertLayoutManager:atIndex:
    method方法。NSLayoutManager类在以下的方法中同样这样处理:-
    (void)setTextStorage:(NSTextStorage *)textStorage; – (NSTextStorage
    *)textStorage; 通常你不用调用setTextStorage方法,但是你可能需要重写它。
    —-(这段难理解,上面属于个人见解,参考原文:If the inserted objects
    need to have a pointer back to the main object, you do this (typically)
    with a set…method that sets the back pointer but does not retain. In
    the case of the insertLayoutManager:atIndex: method, the NSLayoutManager
    class does this in these methods: – (void)setTextStorage:(NSTextStorage
    *)textStorage; – (NSTextStorage *)textStorage; You would normally not
    call setTextStorage: directly, but might want to override it.)
    以上说的集合方法的规则在NSWindow类中都有例子:
– (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
– (void)removeChildWindow:(NSWindow *)childWin;
– (NSArray *)childWindows;
– (NSWindow *)parentWindow;
– (void)setParentWindow:(NSWindow *)window;

Mask与Notification忽略此规则

不要自我参考

—-方法参数

在命名方法参数时候有几个基本规则: —-参数的名字也是骆驼风格
—-不要使用“pointer”或ptr这些词,参数的类型比参数的名字更能说明它是否是指针。
—-避免一俩个字母做参数的名字
—-避免缩写,参数名不差多这几个字母。
一般来讲,以下的一些方法中的关键词通常跟固定的参数搭配:

...action:(SEL)aSelector
...alignment:(int)mode
...atIndex:(int)index
...content:(NSRect)aRect
...doubleValue:(double)aDouble
...floatValue:(float)aFloat
...font:(NSFont *)fontObj
...frame:(NSRect)frameRect
...intValue:(int)anInt
...keyEquivalent:(NSString *)charCode
...length:(int)numBytes
...point:(NSPoint)aPoint
...stringValue:(NSString *)aString
...tag:(int)anInt
...target:(id)anObject
...title:(NSString *)aString

  • 名称不应该自我参考。
—-私有方法

在大多数情况下,私有的方法名称一般跟公共方法的名称都遵循同样的规则作为。然而,还有一个普遍的规则是给私有方法一个前缀,所以很容易区分他们跟公共方法。
即使遵循这些规则,私有方法名称还是可以引起一些特殊问题。当你你编写的Cocoa框架类的子类,你不知道你的私有方法是否无意中重写方法里同名称的私有方法。
在Cocoa框架中命名大多数私有的方法用下划线前缀开头(例如,_foodata),标记方法为私有。对于这条规则,有两个建议:
—–对于你自己的私有方法,不要使用下划线前缀。Apple约定了这条规则;
—–如果是一个大cocoa框架类(如NSView)的子类,你要绝对确保你的私有的方法不同于父类的方法,您可以通过添加你自己独有的前缀来区分。前缀应尽可能的唯一的,也许是一个基于在你公司或项目的形式”xx_”。所以如果你的项目被称为Byte
Flogger,前缀可以是BF_addobject;

虽然之前建议用前缀给私有方法命名,这看起来跟之前说的规则矛盾。但这块情况特殊,我们必须确保子类无意间重写父类的私有方法。
=========================================章节分割线=========================================

图片 6

代码 点评
NSString 可以
NSStringObject 自我参考

—函数命名

Objective-c中实现一个功能可以通过函数和方法。当你的对象是单实例或者处理一个子功能时候,更适合用函数。
函数命名有几下基本原则: —-函数名类似方法名,但有一些例外:
它们用你在类/常数中的前缀开头,并且前缀后的首字母大写。

—-许多函数名字已动词开头,描述函数实现的功能:NSHighlightRect
NSDeallocateObject
—-函数如果是查询一些属性,命名有一些特别的规定:
1.如果函数返回第一个参数的属性,省略动词:unsigned int
NSEventMaskFromType(NSEventType type) float NSHeight(NSRect aRect)
2.如果函数返回值是指针,使用Get:const char
*NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep,
unsigned int *alignp)
3.如果函数返回值是布尔型,函数名用变化的(inflected)动词开头:BOOL
NSDecimalIsNotANumber(const NSDecimal *decimal)
=========================================章节分割线=========================================

1441509984966357.png

  • 掩码(可使用位操作进行组合)和用于通知名称的常量不受该约定限制。

–属性和数据类型命名

这部分讲命名属性、实例变量、常数、通知、异常。

2.前缀
前缀是编程接口命名的重要部分,它们区分了软件的不同功能区域:
前缀可以防止第三方开发者与Apple的命名冲突

代码 点评
NSUnderlineByWordMask 可以
NSTableViewColumnDidMoveNotification 可以
—-属性和实例变量命名

因为属性和存取器方法的对应性质(get方法和set后那部分名称即是属性名字,对应实例变量),所以对于属性的命名基本类似存取器方法的名字,参考存取器方法小节。
—-如果属性是名称/动词意思,格式是:@property (…) type nounOrVerb
例:@property (strong) NSString *title; @property (assign) BOOL
showsAlpha;
—–如果属性是形容词意思,属性名称省略is前缀,并且指定存取器get方法的命名。例如:@property
(assign, getter=isEditable) BOOL editable;
在许多情况,当你声明一个了属性,你同时也确定(synthesize)了相应的实例变量
确保实例变量简明的描述存储的属性,通常你不直接访问实例变量,而是通过存取器方法(在类内部直接访问),为了区别,用下划线前缀;例:

@implementation MyClass {
BOOL _showsTitle;
}

如果你想用某实例变量对应某个属性,在@synthesize中说明:@implementation
MyClass @synthesize showsTitle=_showsTitle;
当添加实例变量的时候,有以下几条规则:
—–避免显示的声明公共的实例变量。开发者只会关心对象的接口,不关心实现的细节。通过声明属性和相应的(synthesizing)实例变量,避免显示声明实例变量。
—–如果需要声明实例变量,用@private 或者
@protected声明。如要继承的实例变量用@protected声明。

—–如果一个实例变量是实例的访问属性(accessible
attribute),确保你已经写了相应的存取器方法

同样可以防止Apple内部的命名冲突

前缀是名称的重要组成部分。它们可以区分软件的功能范围。通常,软件被打包成一个框架,或者多个紧密关联的框架(如FoundationApplication
Kit
框架)。前缀可以防止第三方开发者与Apple之间符号的命名冲突(也可以防止Apple内部不同框架之间的冲突)。

–常数

常数的命名规则跟常数是怎么产生的息息相关。

前缀有指定格式

  • 前缀有规定的格式。它由两到三个大写字母组成,不能使用下划线和子前缀。如下所示:
–枚举常数

—-对于有取值相联系的常数集合,使用枚举(说什么情况使用枚举,跟命名没关系)
—-枚举常数和typedef后面枚举名的命名跟函数的命名规则类似,参考函数命名小节。例:

typedef enum _NSMatrixMode {
NSRadioModeMatrix = 0,
NSHighlightModeMatrix = 1,
NSListModeMatrix = 2,
NSTrackModeMatrix = 3
} NSMatrixMode;

注意上文中_NSMatrixMode 在typedef中没有用。

 

—-你也可以使用不命名的枚举,比如位掩码(bit masks),例如:

enum {
NSBorderlessWindowMask = 0,
NSTitledWindowMask = 1 << 0,
NSClosableWindowMask = 1 << 1,
NSMiniaturizableWindowMask = 1 << 2,
NSResizableWindowMask = 1 << 3
};

 

它由二到三个大写字母组成,不使用下划线和子前缀

前缀 Cocoa框架
NS Foundation
NS Application Kit
AB Address Book
IB Interface Builder
–const修饰的常数

 

—–使用const去创建浮点型常量。可以创建整形常量,如果各整形常量之间没有什么联系,否则,使用枚举。
—-const修饰的常数命名规则,举例说明:const float NSLightGray;
命名规则类似函数,参考函数命名
小节。

命名类、协议、函数、常量和typedef结构体时使用前缀

  • 命名类,协议,函数,常量和结构体时使用前缀。命名成员方法时不使用前缀,因为方法已经在定义它的类的命名空间中。同样的,不使用前缀命名结构体的字段。
–其他类型常数

—-通常不使用#define预编译命令去创建常数。像上文说的,整形常数用枚举,浮点型常数用const修饰
—-使用大写字母符号让编译器决定某段代码是否编译。例如:#ifdef DEBUG

—-注意由编译器定义的宏,有前后各俩个下划线。例如:__MACH__;

—-定义字符串常数,例如作方法名或字典的key等,你要确保编译器识别字符串常数(编译语法检查)。Cocoa提供了许多字符串常量例子,如:APPKIT_EXTERN
NSString *NSPrintCopies
; 字符串的值被指定了常量(注意APPKIT_EXTERN
宏在Objective-C中的像extern声明的作用)

方法名不使用前缀(因为它存在于特定类的命名空间中)

为API元素命名时,遵循以下简单的书写规范:

–通知和异常

通知和异常的命名规则基本相同,但它们有各自特点。

结构体字段不使用前缀

  • 对于多个单词组成的名称,不要使用标点符号作为名称的一部分或者分隔符(下划线,破折号等等);相反,应该大写每个单词的首字母,并将单词联系拼写(例如,runTheWorldsTogether)——即驼峰式命名。请注意以下限制:
–通知

如果一个类有delegate,许多通知都会被delegate接收通过delegate方法。这些通知的名称应该反应相应的delegate方法。例如,一个全局的NSApplication类对象自动注册去接收applicationDidBecomeActive消息,当应用程序发送NSApplicationDidBecomeActiveNotification.消息的时候。通知通过全局的字符串对象定义,格式如下:[Name
of associated class] + [Did | Will] + [UniquePartOfName] +
Notification;
例:

NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification
NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification

 


–异常

 

尽管你可以为了一些目的自由的使用异常(由NSException类和相关函数提供),Cocoa将编程中出现错误,例如数组越界,看做异常。Cocoa不使用异常去处理常规的、预料的错误情况,例如,返回值为nil、NULL、NO或一些错误代码。详细参考《Error
Handling Programming Guide》。

异常通过全局的字符串对象定义,格式如下:[Prefix] +
[UniquePartOfName] + Exception;
其中unique part of the
name是由单词组合而成,每个首字母大写。例如:

NSColorListIOException
NSColorListNotEditableException
NSDraggingException
NSFontUnavailableException
NSIllegalSelectorException

 

=========================================章节分割线=========================================

[图片上传中。。。(7)]
3.书写约定
在命名API元素时,
使用驼峰命名法(如runTheWordsTogether),并注意以下书写约定:
方法名
小写第一个字母,大写之后所有单词的首字母,不使用前缀

  • 方法名的首字母小写,之后每个单词的首字母大写。不要使用前缀。

–通用的缩写和简称

通常你不用缩写你的命名,当你编写接口时候。参考基本命名规则章节。然而,下面所列举的缩写都是众所周知的,你可以继续使用它们。有以下几点需要注意:
—-缩写的替代格式使用在标准C语音库中被允许。例如:“alloc” and “getc”。

—-你可以在参数中更自由的使用缩写。例如:“imageRep”, “col” (for
“column”),“obj”, and “otherWin”

缩写 意义
alloc Allocate
alt Alternate
app 应用程序,例, NSApp全局应用程序对象。 “application” 全拼在delegate方法、通知中等
calc Calculate.
dealloc Deallocate.
func Function.
horiz Horizontal.
info Information
init Initialize
max/min Maximum/Minimum.
msg Message
nib Interface Builder archive.
pboard Pasteboard (but only in constants
rect Rectangle.
Rep Representation (used in class name such as NSBitmapImageRep
temp Temporary.
vert Vertical.

你也可以使用一些计算机行业通用的缩写,例:ASCII、PDF、XML、HTML、URL、RTF、HTTP、TIFF、JPG、PNG、GIF、LZW、ROM、RGB、CMYK、MIDI、FTP

–前言
用公共API开发一个Cocoa框架,插件,或其他可执行目标,里面的命名编写和规范不同于一般应用程序的开发。因为你开…

如果方法名以一个众所周知的大写缩略词开始,该规则不适用

如TIFFRepresentation (NSImage)
1

fileExistsAtPath:isDirectory:

fileExistsAtPath:isDirectory:

该规则的一个例外是方法名以一个广为人知的缩写开头,例如:TIFFRepresentation

函数及常量名
使用与其关联类相同的前缀,并大写首字母

  • 函数名和常量名使用与其关联类相同的前缀,并大写每个单词的首字母。

1
2

NSRunAlertPanel

NSRunAlertPanelNSCellDisabled

NSCellDisabled

  • 避免在方法名中使用下划线作为前缀来表示私有方法(可以在实例变量名中使用下划线作为前缀)。Apple保留了该规范的使用。如果第三方这样使用,可能会导致命名空间冲突;他们可能无意的用自己的方法覆盖了已经存在的私有方法,这会导致严重的后果。请参考“私有方法”一节。

标点符号
由多个单词组成的名称,别使用标点符号作为名称的一部分

类名应该包含一个明确描述类是什么或者做什么的名词。类名要有一个合适的前缀。FoundationApplication
Kit
框架很多这样的例子,例如NSStringNSDateNSScannerNSApplicationUIApplicationNSButtonUIButton

分隔符(下划线、破折号等)也不能使用

协议应该根据如何分组行为来命名:

避免使用下划线作为私有方法的前缀,Apple保留这一方式的使用

  • 大部分协议组合相关的方法,而不关联任何具体的类。这种类型的协议名称不要与类名混淆。通常使用动名词的格式:

强行使用可能会导致命名冲突,即Apple已有的方法被覆盖,这会导致灾难性后果

代码 点评
NSLocking
NSLock 不好

实例变量使用下划线作为前缀还是允许的

  • 有些协议组合一些不相关的方法(而不是创建多个独立的小协议)。这些协议倾向于与某个类关联,该类是协议的主要体现者。这种情况下,协议名称与类名一样。

4.class与protocol命名
class
class的名称应该包含一个名词,用以表明这个类是什么(或者做了什么),并拥有合适的前缀

NSObject协议就是这样一个例子。该协议组合不相关的方法,包括查询对象在类继承关系中位置的方法,调用特殊方法的方法,增加或减少引用计数的方法。因为NSObject类是这些方法的主要体现者,所以用类名命名这个协议。

如NSString、NSDate、NSScanner、UIApplication、UIButton

如何命名头文件很重要,因为使用的命名规范表明了头文件的内容。

不关联class的protocol
大多数protocol聚集了一堆相关方法,并不关联class

  • 声明独立的协议或类。如果类或协议不是分组的一部分,把它的声明放在单独的文件中,名称与类或协议相同。

这种protocol使用ing形式以和class区分开来

头文件 声明
NSLocale.h NSLocale

图片 7

  • 声明相关的类和协议。对于一组相关的声明,把声明放在一个文件中,文件名为主要的类,类别或协议。

1441510247983445.png

头文件 声明
NSString.h NSStringNSMutableString
NSLock.h NSLocking协议和NSLockNSConditionLockNSRecursiveLock

关联class的protocol
一些protoco聚集了一堆无关方法,并试图与某个class关联在一起,由这个class来主导

  • 包括框架头文件。每个框架应该有一个与框架同名的头文件,其中包括该框架所有公开的头文件。

  • 添加API到另一个框架中的类。如果在框架中声明的方法是另一个框架中某个类的类别,在原类名后添加“Additions”;例如Application
    Kit
    中的NSBundleAdditions.h头文件。

  • 相关的函数和数据类型。讲相关的函数,常量,结构体,以及其它数据类型放在同一个头文件中,并以合适的名字命名,例如NSGraphics.hApplication
    Kit
    )。

这种protocol与class同名

方法可能是编程接口中最常见的元素,因此要非常小心的为它们命名。本节讨论方法命名的以下几个方法:

如NSObject protocol

为方法命名时,记住以下一般性指南:

5.头文件
头文件的命名极其重要,因为它可以指出头文件包含的内容:
声明一个孤立的class或protocol

  • 第一个单词的首字母小写,之后的每个单词的首字母大写。不要使用前缀。请参考“书写规范”。有两种例外情况:第一,使用广为人知的大写字母缩写命名方法(例如TIFF或PDF);第二,使用前缀分组和确定私有方法。

  • 表示对象行为的方法,以动词开头:

将声明放入单独的文件

使头文件名与声明的class/protocol相同

- invokeWithTarget:target;- selectTabViewItem:(NSTabViewItem *)tabViewItem

[图片上传中。。。(9)]
声明关联的class或protocol

不要使用“do”或“does”作为名称的一部分,因为这些助动词没有实际意义。同样的,动词之前不要使用副词或形容词。

将关联的声明(class/category/protocol)放入同一个头文件

  • 如果方法返回接收者的某个属性,直接用属性名命名。不要使用“get”,除非间接返回一个或多个值。

头文件名与主要的class/category/protocol相同

方法名 点评
– cellSize; 正确
– calcCellSize; 错误
– getCellSize; 错误

[图片上传中。。。(10)]
Framework头文件

请参考“访问方法”一节。

每个framework都应该有一个同名头文件

  • 在所有参数之前使用关键字。

Include了框架内其他所有头文件

方法名 点评
– sendAction:aSelector toObject:anObject forAllCells:flag; 正确
– sendAction:aSelector :anObject :flag; 错误

图片 8

  • 参数之前的单词要能描述该参数。

1441510294801244.png

方法名 点评
– viewWithTag:(NSInteger)aTag; 正确
– taggedView:aTag; 错误

添加API到另一个framework

  • 当创建的方法比继承的方法更具体时,在已存在的方法后添加新的关键字。

如果要在一个framework中为另一个framework的class
catetgory添加方法,加上单词“Additions”

方法名 点评
– initWithFrame:frameRect; NSView,UIView
– initWithFrame:frameRect mode:aMode cellClass:factoryId numberOfRows:rowsHigh numberOfColumns:colsWide; NSMatrix,NSView的子类

如Application Kit的NSBundleAdditions.h 文件

  • 不要使用“and“连接关键字,该关键字是接收者的属性。

关联的函数、数据类型

方法名 点评
– runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; 正确
– runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; 错误

如果你有一组关联的函数、常量、结构体或其他数据类型,将它们放到一个名字合适的头文件中

虽然上面的例子中使用”and“看起来不错,但当方法有更多关键字时就会有问题。

如Application Kit的NSGraphics.h

  • 当方法描述两个独立的行为时,用”and“连接它们。

二、方法
1.通用原则
以小写字母开始,之后单词的首字母大写

方法名 点评
*- openFile:(NSString *)fullPath withApplication:(NSString )appName andDeactivate:flag; NSWorkspace

以众所周知的缩写开始可以大写,如TIFF、PDF

访问方法是对象属性的读取和设置方法,其命名的特定推荐格式依赖于如何描述属性:

私有方法可以加前缀

  • 如果用名词描述属性,格式为:

如果方法代表对象接收的动作,以动词开始

不要使用 do 或 does 作为名字的一部分,因为助动词在这里很少有实际意义

- noun;- setNoun:aNoun;

同样的,也别在动词之前使用副词和形容词

例如:

1
2

- (NSString *)title;- setTitle:(NSString *)aTitle;
  • (void)invokeWithTarget:(id)target;

  • (void)selectTabViewItem:(NSTabViewItem *)tabViewItem

  • 如果用形容词描述属性,格式为:

如果方法返回接收者的属性,以 接收者 + 接收的属性 命名

除非间接返回多个值,否则不要使用 get 单词(为了与accessor methods区分)

- isAdjective;- setAdjective:flag;

[图片上传中。。。(12)]
在所有参数之前使用关键字
[图片上传中。。。(13)]
确保参数之前的关键字充分描述了参数
[图片上传中。。。(14)]
创建自定义 init 方法时,记得指明关联的元素
[图片上传中。。。(15)]
不要使用 and 来连接作为接收者属性的关键字
虽然下面的例子使用 and 看似不错,但是一旦参数非常多时就容易出现问题

例如:

[图片上传中。。。(16)]
除非方法描述了两个独立的操作,才使用 and 来连接它们
[图片上传中。。。(17)]
2.getter和setter方法(Accessor Methods)
如果property表示为名词,格式如下

- isEditable;- setEditable:flag;
  • (type)noun;

  • (void)setNoun:(type)aNoun;

  • (BOOL)isAdjective;

  • 如果用动词描述属性,格式为:(动词要使用一般现在时)

1
2

  • (NSString *)title;

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

- verbObject;- setVerbObject:flag;

如果property表示为形容词,格式如下

例如:

  • (BOOL)isAdjective;

  • (void)setAdjective:(BOOL)flag;

- showsAlpha;- setShowsAlpha:flag;

1
2

  • 不要把动词的分词形式作为形容词使用:
  • (BOOL)isEditable;

  • (void)setEditable:(BOOL)flag;

方法名 点评
– setAcceptsGlyphInfo:flag; 正确
– acceptsGlyphInfo; 正确
– setGlyphInfoAccepted:flag; 错误
– glyphInfoAccepted; 错误

如果property表示为动词,格式如下(动词用一般现在时)

  • 可以使用情态动词(can,should,will等)明确意图,但不要使用”do“或”does“。
  • (BOOL)verbObject;

  • (void)setVerbObject:(BOOL)flag;

方法名 点评
– setCanHide:flag; 正确
– canHide; 正确
– setShouldCloseDocument:flag; 正确
– shouldCloseDocument; 正确
– setDoesAcceptGlyphInfo:flag; 错误
– doesAcceptGlyphInfo; 错误

1
2

  • 只在方法简介返回对象和值时使用”get“。当需要返回多个项时才使用这种格式的方法。
  • (BOOL)showsAlpha;

  • (void)setShowsAlpha:(BOOL)flag;

方法名 点评
*- getLineDash:pattern count:count phase:(float )phase; NSBezierPath

不要把动词的过去分词形式当作形容词使用
[图片上传中。。。(18)]
你可能使用情态动词(can、should、will等)来增加可读性,不过不要使用 do或
does
[图片上传中。。。(19)]
只有方法需要间接返回多个值的情况下才使用 get
像这种接收多个参数的方法应该能够传入nil,因为调用者未必对每个参数都感兴趣
[图片上传中。。。(20)]
3.Delegate方法
以发送消息的对象开始
省略了前缀的类名和首字母小写
1
2

像上面这样的方法,实现时应该允许接收NULL作为in/out参数,表示调用者不需要一个或多个返回值。

  • (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;

  • (BOOL)application:(NSApplication *)sender openFile:(NSString
    *)filename;

特定事件发生时,对象在其代理中(如果代理实现了代理方法)调用代理方法。它们有独特的格式,同样也适用于对象的数据源方法。

以发送消息的对象开始的规则不适用下列两种情况
只有一个sender参数的方法
1

  • 以发送消息的对象的类名开头,省略类的前缀,并小写第一个字母:
  • (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;

响应notification的方法(方法的唯一参数就是notification)
1

- tableView:(NSTableView *)tableView shouldSelectRow:row;- application:(NSApplication *)sender openFile:(NSString *)filename;
  • (void)windowDidChangeScreen:(NSNotification *)notification;
  • 冒号紧跟在类名之后(参数是被代理对象的引用),除非该方法只有一个”sender“参数。

使用单词 did 和 will 来通知delegate
did 表示某些事已发生

will 表示某些事将要发生

- applicationOpenUntitledFile:(NSApplication *)sender;

1
2

  • 作为响应通知结果的方法是一个例外,此时唯一的参数是通知对象。
  • (void)browserDidScroll:(NSBrowser *)sender;

  • (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;

询问delegate是否可以执行某个行为时可以使用 did 或 will,不过 should
更完美
1

- windowDidChangeScreen:(NSNotification *)notification;
  • (BOOL)windowShouldClose:(id)sender;
  • 通知代理对象操作已经发生或即将发生的方法使用“did”或“will”。

**4.集合方法 **
为了管理集合中的元素,集合应该有这几个方法

  • (void)addElement:(elementType)anObj;

  • (void)removeElement:(elementType)anObj;

  • (NSArray *)elements;

- browserDidScroll:(NSBrowser *)sender;- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;

1
2
3

  • 询问代理对象能否执行某个操作可以使用“did”或“will”,但最好使用“should”。
  • (void)addLayoutManager:(NSLayoutManager *)obj;

  • (void)removeLayoutManager:(NSLayoutManager *)obj;

  • (NSArray *)layoutManagers;

如果集合是无序的,返回一个NSSet比NSarray更好
如果需要在集合中的特定位置插入元素,使用类似下面的方法
1
2

- windowShouldClose:sender;
  • (void)insertLayoutManager:(NSLayoutManager *)obj
    atIndex:(int)index;

  • (void)removeLayoutManagerAtIndex:(int)index;

管理对象集合的对象(集合中的对象叫做元素)方法具备如下的格式:

其他集合方法示例
1
2
3
4
5

- addElement:(elementType)anObj;- removeElement:(elementType)anObj;- (NSArray *)elements;
  • (void)addChildWindow:(NSWindow *)childWin
    ordered:(NSWindowOrderingMode)place;

  • (void)removeChildWindow:(NSWindow *)childWin;

  • (NSArray *)childWindows;

  • (NSWindow *)parentWindow;

  • (void)setParentWindow:(NSWindow *)window;

例如:

**5.方法参数 **
参数名以小写字母开始,之后的单词首字母大写

- addLayoutManager:(NSLayoutManager *)obj;- removeLayoutManager:(NSLayoutManager *)obj;- (NSArray *)layoutManagers;

1

下面是集合方法命名的一些限制和规定:

如:removeObject:(id)anObject

  • 如果集合是无序的,返回NSSet对象,而不是NSArray对象。

  • 如果在指定位置插入元素的功能很重要,使用类似下面的方法代替或者添加到上面的规范中:

别使用 ”pointer” 或 ”ptr” 命名

参数类型里就已表明它是否是一个指针

- insertLayoutManager:(NSLayoutManager *)obj atIndex:index;- removeLayoutManagerAtIndex:index;

避免只有一到二个字母的参数名

集合方法的实现需要考虑以下细节:

避免只有几个字母的缩写

  • 这些方法通常拥有插入对象,所以添加或插入的代码需要retain元素,并在移除的代码中release元素。

  • 如果被插入的对象需要主对象的指针时,通常使用set…方法设置该指针,并且不要retain。在insertLayoutManager:atIndex:方法中,NSLayoutManager类使用如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

…action:(SEL)aSelector

- setTextStorage:(NSTextStorage *)textStorage;- (NSTextStorage *)textStorage;

…alignment:(int)mode

通常不会直接调用setTextStorage:方法,而是覆写它。

…atIndex:(int)index

另一个关于上面集合方法规范的例子是NSWindow类:

…content:(NSRect)aRect

- addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;- removeChildWindow:(NSWindow *)childWin;- (NSArray *)childWindows; - (NSWindow *)parentWindow;- setParentWindow:(NSWindow *)window;

…doubleValue:(double)aDouble

命名方法参数需要考虑以下一般性规则:

…floatValue:(float)aFloat

  • 与方法名一样,参数名的第一个单词的首字母小写,之后的每个单词的首字母大写(例如:removeObject:anObject)。

  • 不要在名称中使用pointer或ptr。用参数的类型,而不是名称声明是否是指针。

  • 避免使用one-,two-letter作为参数名。

  • 避免少写几个字符而使用缩写。

…font:(NSFont *)fontObj

按惯例,结合使用下面的关键字和参数:

…frame:(NSRect)frameRect

...action:aSelector...alignment:mode...atIndex:index...content:aRect...doubleValue:aDouble...floatValue:aFloat...font:fontObj...frame:frameRect...intValue:anInt...keyEquivalent:(NSString *)charCode...length:numBytes...point:aPoint...stringValue:(NSString *)aString...tag:anInt...target:anObject...title:(NSString *)aString

…intValue:(int)anInt

大多数情况下,私有方法的命名与公共方法命名的规范相同。但通常给私有方法加一个前缀,以便与公共方法区分开来。即使在这个规范下,私有方法名还是会导致奇怪的问题。设计一个从Cocoa框架继承的子类时,不知道自己的私有方法是否无意的覆盖了框架中同名的私有方法。

…keyEquivalent:(NSString *)charCode

Cocoa框架中大部分私有方法名使用下划线(例如:_fooData)标志为私有的。因此遵循下面两条建议:

…length:(int)numBytes

  • 不要使用下划线作为私有方法的前缀,Apple保留了这个规范。

  • 如果继承Cocoa框架中的一个超大类(例如:NSViewUIView),并想要完全区分父类私有方法和自己的私有方法,可以为私有方法添加自己的前缀。这个前缀应该尽可能唯一,例如基于公司或工程的名称,如“XX_”这样的格式。如果工程名是“Byte
    Flogger”,前缀可以是“BF_addObject:”。

…point:(NSPoint)aPoint

尽管为私有方法添加前缀的建议与之前为方法命名的规范自相矛盾,但这里的目的不一样:防止无意覆写父类中的私有方法。

…stringValue:(NSString *)aString

Objective-C允许使用函数描述行为,如同方法一样。当对象是单例时,或者处理明显的函数式子系统时,应该使用函数而不是类方法。

…tag:(int)anInt

函数命名应该遵循如下一般性的规则:

…target:(id)anObject

  • 函数名与方法名类似,但有几点不同:

…title:(NSString *)aString

6.私有方法
不要使用下划线作为私有方法的前缀,Apple保留这一使用方式
因为若是你的私有方法名已被Apple使用,覆盖它将会产生极难追踪的BUG
如果继承自大型Cocoa框架(如UIView),请确保子类的私有方法名与父类不一样
可以为私有方法加一个前缀,如公司名或项目名:XX_
例如你的项目叫做Byte Flogger,那么前缀可能是:BF_addObject
总之,为子类的私有方法添加前缀是为了不覆盖其父类的私有方法
三、函数
函数的命名类似方法,但有两点要注意
你使用的类和常量拥有相同的前缀

  • 它们以与类和常量相同的前缀开头。
  • 前缀之后的第一个单词的首字母大写。

前缀后的首字母大写

许多函数名以描述其作用的动词开始
1
2

  • 大部分函数以动词开头,描述该函数的行为:

NSHighlightRect

NSDeallocateObject

NSHighlightRectNSDeallocateObject

查询属性的函数有进一步的命名规则
如果函数返回首个参数的属性,省略动词
1
2

查询属性的函数有更多的命名规则:

unsigned int NSEventMaskFromType(NSEventType type)

  • 如果函数返回第一个参数的属性,省略动词。

float NSHeight(NSRect aRect)

如果通过reference返回了值,使用 “Get”
1

unsigned int NSEventMaskFromType(NSEventType type)float NSHeight(NSRect aRect)

const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int
*sizep, unsigned int *alignp)

  • 如果通过引用返回值,使用“Get”。

如果返回的是boolean值,应该灵活使用动词
1

BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)

const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsigned int *alignp)

四、Property及其他
1.Property与实例变量
1.1 Property
Property命名规则与第二章accessor methods一样(因为两者紧密联系)
如果property表示为一个名词或动词,格式如下
@property (…) 类型 名词/动词 ;
1
2

  • 如果返回值是boolean类型,函数用判断动词开头。

@property (strong) NSString *title;

@property (assign) BOOL showsAlpha;

BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)

如果property表示为一个形容词
可省略 ”is” 前缀

本节描述声明属性,实例变量,常量,通知和异常的命名规范。

但要指定getter方法的惯用名称

一个声明的属性实际上声明了属性的一个访问方法,因此属性的命名规范大体上与访问方法相同。如果属性用名称或动词描述,格式为:

1

@property  type nounOrVerb;

@property (assign, getter=isEditable) BOOL editable;

例如:

1.2 实例变量
通常不应该直接访问实例变量
init、dealloc、accessor methods等方法内部例外
实例变量以下划线 “_” 开始
确保实例变量描述了所存储的属性
1
2
3

@property  NSString *title;@property  BOOL showsAlpha;

@implementation MyClass {

如果属性用形容词描述,省略“is”前缀,但指明get访问器的规范的名称,例如:

BOOL _showsTitle;

@property (assign, getter=isEditable) BOOL editable;

}

多数情况下,使用一个声明的属性时,同时生成了一个相应的实例变量。

如果想要修改property的实例变量名,使用 @synthesize语句
1
2

确保实例变量简明扼要的描述了存储的属性。通常不直接访问实例变量,而是使用访问方法(在init和dealloc方法中直接访问实例变量)。为了达到这个目的,在实例变量名之前添加下划线作为前置,例如:

@implementation MyClass

@implementation MyClass { BOOL _showsTitle;}

@synthesize showsTitle=_showsTitle;

如果使用一个生命的属性生成实例变量,在@synthesize中指定实例变量的名称。

为一个class添加实例变量时,有几点需要注意:
避免声明公有实例变量

@implementation MyClass@synthesize showsTitle=_showsTitle;

开发者关注的应该是对象接口,而不是其数据细节

为类添加实例变量时需要考虑以下几个方面:

你可以通过使用property来避免声明实例变量

  • 避免显式的声明public实例变量。开发者应该关注对象的接口,而不是如何存储数据的细节。通过声明属性和生成相应的实例变量避免显式的声明实例变量。

  • 如果需要声明实例变量,用@private或@protected显式的声明。如果希望类被继承,并且子类需要直接访问数据,使用@protected。

  • 如果实例变量是类实例的可访问属性,确保使用访问方法(尽可能使用声明的属性)。

如果需要声明实例变量,指定关键字@private 或 @protected

常量命名规则根据创建方式的不同而大不相同。

如果你希望子类可以直接访问某个实例变量,使用 @protected 关键字

4.2.1 枚举常量

  • 使用枚举定义一组相关的整数常量。

  • 枚举常量与其typedef命名遵循函数的命名规范。下面的例子来自NSMatrix.h。本例中typedef标识(_NSMatrixMode)不是必须的。

typedef enum _NSMatrixMode { NSRadioModeMatrix = 0, NSHighlightModeMatrix = 1, NSListModeMatrix = 2, NSTrackModeMatrix = 3} NSMatrixMode;
  • 可以创建不具名枚举,比如位掩码。

enum { NSBorderlessWindowMask = 0, NSTitledWindowMask = 1 << 0, NSClosableWindowMask = 1 << 1, NSMiniaturizableWindowMask = 1 << 2, NSResizableWindowMask = 1 << 3 };

如果一个实例变量是某个类可访问的属性,确保写了accessor methods

4.2.2 使用const创建的常量

  • 使用const创建浮点常量。如果常量与其它常量不相关,可以使用const创建整数常量;否则使用枚举。

  • const常量格式如下面的声明所示:

const float NSLightGray;

枚举常量的命名规范跟函数命名规范相同。

如果有可能,还是使用property

4.2.3 其它类型的常量

  • 通常不适用#define预处理命令创建常量。对于整数常量,使用枚举,浮点数常量使用const。

  • 使用大写字母定义预处理宏,来决定代码块是否执行。例如:

#ifdef DEBUG
  • 编译器定义的宏的头尾都有双下划线,例如:

__MACH__
  • 定义常量字符串用作通知名和字典的键。使用常量字符串,编译器可以执行拼写检查。Cocoa框架提供了很多常量字符串的例子:

APPKIT_EXTERN NSString *NSPrintCopies;

字符串在实现文件中赋值。(注意:APPKIT_EXTERN宏在Objective-C中等价于extern)

通知和异常的命名遵循相似的规则,但它们有各自的推荐使用模式。

**2.常量 **
2.1 枚举常量
使用枚举来关联一组integer常量
枚举常量和typedef遵循函数的命名规范,下面的例子是 NSMatrix.h
1
2
3
4
5
6

4.3.1 通知

如果一个类有代理,那它的大部分通知可能由代理类的代理方法接收。这些通知的名称应该能够反应对应的代理方法。例如,当应用程序提交NSApplicationDidBecomeActiveNotification通知时,全局的NSApplication对象的代理自动注册接收applicationDidBecomeActive:消息。

通知由如下形式的全局NSString对象标识:

[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification

例如:

NSApplicationDidBecomeActiveNotificationNSWindowDidMiniaturizeNotificationNSTextViewDidChangeSelectionNotificationNSColorPanelColorDidChangeNotification

typedef enum _NSMatrixMode {

4.3.2 异常

虽然可以因为任何目的而使用异常(由NSException类和相关函数实现),但Cocoa使用异常来处理类似数组越界的编程错误。Cocoa不适用异常处理常规的,可预料的错误。这些情况下,使用nil,NULL,NO,或错误代码之类的返回值。

异常由如下形式的全局NSString对象标识:

[Prefix] + [UniquePartOfName] + Exception

名称的唯一部分(UniquePartOfName)部分由单词组成,每个单词的第一个字母大写。例如:

NSColorListIOExceptionNSColorListNotEditableExceptionNSDraggingExceptionNSFontUnavailableExceptionNSIllegalSelectorException

设计编程接口时,通常不使用缩写(参考“一般性规则”)。然后下面列出的缩写要么是相沿成习,要么是过去广泛使用的,所以可以继续使用。关于缩写有一些额外的注意事项:

  • 标准C库中长期使用的缩写形式是可以接受的,例如:“alloc”,“getc”。

  • 在参数名中可以更自由的使用缩写,例如:“imageRep”,“col”,“obj”,“otherWin”。

缩写 含义和注释
alloc Allocate
app Application。例如,全局application对象NSApp。但在代理方法,通知等中,应该使用“application”全拼。
alt Alternate
calc Calculate
dealloc Deallocate
func Function
horiz Horizontal
info Information
init Initialize
int Integer
max Maximum
min Minimum
msg Message
nib Interface Builder文件
pboard Pasteboard
rect Rectangle
Rep Representation(在类名中使用,如NSBitmapImageRep)
temp Temporary
vert Vertical

可以使用计算机行业的常见缩写和首字母缩写,例如:

ASCIIPDFXMLHTMLURLRTFHTTPTIFFJPGPNGGIFLZWROMRGBCMYKMIDIFTP

没有开发框架,不敢随便翻译,以后有机会再翻译。

NSRadioModeMatrix = 0,

NSHighlightModeMatrix = 1,

NSListModeMatrix = 2,

NSTrackModeMatrix = 3

} NSMatrixMode;

你可以为bit masks之类的东西创建一个匿名枚举
1
2
3
4
5
6
7

enum {

NSBorderlessWindowMask = 0,

NSTitledWindowMask = 1 << 0,

NSClosableWindowMask = 1 << 1,

NSMiniaturizableWindowMask = 1 << 2,

NSResizableWindowMask = 1 << 3

};

**2.2 使用const关键字的常量 **
使用const关键字来创建一个float常量
你可以使用const关键字来创建一个与其他常量不相关的integer常量,否则,使用枚举
使用const关键字的常量也遵循函数的命名规则
1

const float NSLightGray;

**2.3 其他常量类型 **
通常不应使用 #define 预编译指令来创建常量

integer常量,使用枚举

float常量,使用 const 修饰符

对 #define 预编译指令,大写所有字母

比如 DEBUG 判断

1

ifdef DEBUG

注意宏命令的字首和字尾都有双下划线

1

MACH

定义NSString常量来作为Notification和Key值

这样做可以有效防止拼写错误

1

APPKIT_EXTERN NSString *NSPrintCopies;

3.Notifications与Exceptions
**3.1 Notifications **
Notification的格式
1

[Name of associated class] + [Did | Will] + [UniquePartOfName] +
Notification

1
2
3
4

NSApplicationDidBecomeActiveNotification

NSWindowDidMiniaturizeNotification

NSTextViewDidChangeSelectionNotification

NSColorPanelColorDidChangeNotification

**3.2 Exceptions **
Exception的格式

1

[Prefix] + [UniquePartOfName] + Exception

1
2
3
4
5

NSColorListIOException

NSColorListNotEditableException

NSDraggingException

NSFontUnavailableException

NSIllegalSelectorException

五、缩写
设计编程接口时通常不应使用缩写,但下列已被广泛使用的缩写名称除外
标准C库中的缩写名,如:alloc、init
参数名可自由使用缩写,如:imageRep、col、obj、otherWin
[图片上传中。。。(21)]
[图片上传中。。。(22)]

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 澳门新葡亰官网app 版权所有