编码规范,objective-c编码规范

参考了<<C++编程规范 101条规则,准则与最佳实践>>

1.匈牙利命名 和 不要盲目使用匈牙利命名

命名规范是程序书写规范中最重要也是最富争议的地方,自古乃兵家必争之地。命名规范有何用?四个字:名正言顺。好的舞鞋是让舞者感觉不到其存在的舞鞋,坏的舞鞋是让舞者带着镣铐起舞。


匈牙利命名法的成本:匈法的表现形式为给变量名附加上类型名前缀,例如:nFoo,szFoo,pFoo,cpFoo分别表示整型变量,字符串型变量,指针型变量和常指针型变量。可以看出,匈法将变量的类型信息从单一地点(声明变量处)复制到了多个地点(使用变量处),这是冗余法。冗余法的成本之一是要维护副本的一致性。这个成本在编写和维护代码的过程中需要改变变量的类型时付出。冗余法的成本之二是占用了额外的空间。一个优秀的书写者会自觉地遵从一个法则:代码最小组织单位的长度以30个自然行以下为宜,如果超过50行就应该重新组织。一个变量的书写空间会给这一法则添加不必要的难度。

匈牙利命名法的收益是含糊的,无法预期的。

 

  Charles Simonyi(他后来成为微软的著名程序员)设计了一种以前缀为基础的命名方法,这种方法后来称为"匈牙利表示法"以记念他.他的思想是根据每个标识符所代表的含义给它一个前缀.微软后来采用了这个思想,给每个标识符一个前缀以说明它的数据类型.因此,整型变量的前缀是n,长整型变量是nl,字符型数组变量是ca,以及字符串(以空类型结尾的字符数组)以sz为前缀.这些名字可能会非常古怪.比如说:lpszFoo表示"Foo"是一个指向以空字符为结尾的字符串的长整型指针.

这种方法的优点是使人能够通过变量的名字来辨别变量的类型,而不比去查找它的定义遗憾的是,这种方法不仅使变量名字非常绕口,而且使改变变量类型的工作变得十分艰巨.在Windows3.1中,整型变量为16为宽.如果我们在开始时采用了一个整型变量,但是在通过30---40个函数的计算之后,发现采用整型变量宽度不够,这时我们不仅要改变这个变量的类型,而且要改变这个变量在这30--40个函数中的名字.


因为不切实际,除了一些顽固的Windows程序员外,已经没有人再使用"匈牙利表示法"了。毫无疑问,在某种场合它依然存在,但大部分人现在已经抛弃它了。一般而言,输入前缀是一种糟糕的想法,因为它把变量与其类型紧紧地绑在了一起


http://www.cppblog.com/justin-shi/archive/2008/05/02/48615.html
http://www.cnitblog.com/ffan/archive/2005/09/21/2815.html
匈命名规范表
http://dev.csdn.net/htmls/34/34000.html


将类型信息并入变量名的记法,是混用了类型不安全语言(特别是C)中的设施,这在面向对象语言中是可以存在的,但是有害无益,在泛型编程中则根本不可行。所以,任何C++编程规范都不应该要求使用匈牙利记法,而在规范中选择禁用该记法则是合理的。

关于对象的类型,编译器知道的要比你多得多。改变变量的名字,蕴入类型信息,其好处实在有限,而且使之更脆弱。如果说在C风格的语言里使用匈牙利记法还存在一些理由的话(即使这点也存在争议),那么在类型安全的语言中使用它则是有害无利。

如果知道类型名,便会引出变量名,即变量名本身就可以体现出自己的类型。如果加入类型标识,万一类型发生改变,必须修改变量名。如:int改为了long.

对于编程人员,瞬间知道变量的作用域比瞬间知道它的类型有用的多

匈牙利命名法更已不适合现在的面向对象语言。

但对于类型是数组,字典等集合体的变量,在名称的最后标识出类型信息更好。也允许在局部很短的作用域内使用这种命名法。


2.关于有人盲目推荐“不要在循环体内定义变量”,http://topic.csdn.net/t/20061229/10/5263622.html

   参考 java:string博文。

   变量声明在for内外对于GC没有太大区别。先不论gc时机和具体回收的堆内容的不确定性,就光看栈引用和堆对象的关系而言,两种写法都只会新创建N个堆对象,同时,任意时刻,都只有一个栈引用一个堆对象。

   循环体外定义的变量只生成一次,循环体内定义变量理论上每次循环都回生成变量。生成一个变量,系统仍然要分配内存空间的,所以效率较低,但是现在的编译器都是带优化的,编译的时候一优化就一样了。可能会被优化为,只在第一次循环才声明,编译器会记住此声明,后面的循环就不再声明了。

  例如:

   for( ...)
{
   int i=5;   //只在第一次循环才声明
}

试想一下,如果想当然的认为是每次循环都会定义,那么把这个循环展开就会是
int i=5;
int i=5;
......
显示是不能为编译器接受的。

另外,在VC里调试
void main()
{
for(int i=0;i<5;i++)
{
int* num = new int;
}
}
可以发现每次循环时 &num是同一个值,指针本身这个32位整数值是不变的。
  在循环体外声明一个只有循环体内才使用的变量是一个不良习惯,这是典型老式C语言的编程风格,就像在C语言中滥用全局变量一样,这样会扰乱上下文变量的定义和语义,造成程序本身的不可读性。非持久性状态变量声明尽量局部化,这是模块化和面向对象思想的一般准则。

  随着硬件水平的提高,清晰、易懂的代码更优于不清晰,不易懂但效率只是略高的代码。
  从普遍意义上来说,“不要在循环体内定义变量”只适用于在心理上对效率差要求极高的高手。


   自动生存期变量:其内存空间在程序执行到定义它们的复合语句时才分配,定义它们的复合语句结束时,空间被收回,局部变量和函数参数一般具有自动生存期。
   当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
   栈展开:因发生异常而逐步退出复合语句和函数定义,被称为栈展开(stack unwinding)。栈展开才是异常处理的核心技术。随着栈展开,在退出的复合语句和函数定义中声明的局部变量的生命期也结束了。在栈中分配的局部量占用的资源也被释放,由系统回收。


3.google出的C++编码规范 英文版

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#File_Names


Google Objective-C Style Guide 中文版
http://www.cocoachina.com/macdev/objc/2011/0328/2740.html

4.ios编码规范摘要

4.1.格式化代码

     *号的位置

     括号对齐

      方法名和参数间不留空格

      当参数过长时,每个参数占用一行,以冒号对齐如果方法名比参数名短,每个参数占用一行,至少缩进4个字符,且为垂直对齐(而非使用冒号对齐)

      使用分段宏,注明函数来源

4.2.命名

       类名使用首字母大写的形式分割单词,camel case,驼峰式命令法。
       在面向特定应用的代码中,类名应尽量避免使用前缀,每个类都使用相同的前缀影响可读性。
       在面向多应用的代码中,推荐使用前缀,这可以避免重名,还声明了代码来源。如:GTMSendMessage

       方法名的首字母小写,且使用首字母大写的形式分割单词。方法的参数使用相同的规则。
       方法名+参数应尽量读起来像一句话(如:)。在这里查看苹果对方法命名的规范。
       getter的方法名和变量名应相同。不允许使用“get”前缀。
        本规则仅针对Objective-C代码,C++代码使用C++的习惯 


       变量名应使用容易意会的应用全称,且首字母小写,且使用首字母大写的形式分割单词,参照symbian,参数以a开头。
       成员变量使用“_”作为前缀(如:“NSString *_varName;”。虽然这与苹果的标准(使 
用“_”作为后缀)相冲突,但基于以下原因,仍使用“_”作为前缀。
▪ 使用“_”作为前缀,更容易在有代码自动补全功能的IDE中区分“属性 
(self.userInfo)”和“成员变量(_userInfo)” 

       与去掉“_”前缀的成员变量相同,使用@synthesize将二者联系起来
       常量(#define, enums, const等)使用小写“k”作为前缀,首字母大写来分割单词。如:  kInvalidHandle

       以 alloc/new/copy/mutableCopy 开头的函数,只生成对象,不是其持有者。


4.3.逻辑

       在初始化方法中,不要将变量初始化为“0”或“nil”,那是多余的。但在c++中完全必须初始化。
       使用#import引入Ojbective-C和Ojbective-C++头文件,使用#include引入C和C++头 文件
       import根框架(root frameworks),而非各单个文件
, 虽然有时我们仅需要框架(如Cocoa 或 Foundation)的某几个头文件,但引入根文件编译
器会运行的更快。因为根框架(root frameworks)一般会预编译,所以加载会更快。
        创建临时对象时,尽量同时在同一行中 autorelease 掉,而非使用单独的 release 语句
        虽然这样会稍微有点慢,但这样可以阻止因为提前 return 或其他意外情况导致的内存泄露。 
   通盘来看这是值得的。如:
        dealloc的顺序要与变量声明的顺序相同
, 这有利于review代码
,如果dealloc中调用其他方法来release变量,将被release的变量以注释的形式标注清楚

       NSString的属性的setter使用“copy” ,禁止使用retain,以防止意外的修改了NSString变量的值。如:
       避免抛出异常(Throwing Exceptions)
       对 nil 的检查
▪ 仅在有业务逻辑需求时检查nil,而非为了防止崩溃
       向 nil 发送消息不会导致系统崩溃,Objective-C运行时负责处理。
       将int值转换为BOOL时应特别小心。避免直接和YES比较
       Objective-C中,BOOL被定义为unsigned char,这意味着除了 YES(1) 和NO(0)外它 
还可以是其他值。禁止将int直接转换(cast or convert)为BOOL。
       delegate对象使用assign,禁止使用retain。因为retain会导致循环索引导致内存泄露, 
并且此类型的内存泄露无法被Instrument发现,极难调试
       成员变量命名为_delegate,属性名为delegate 
◦

       不要在与view相关的类中添加过多的业务逻辑代码,这让代码的可重用性很差 
▪ Controller负责业务逻辑代码,且Controller的代码与view尽量无关

       如果并非所有回调方法都是必须的,使用@optional标示

        init方法和dealloc方法是是最常用的方法,所以将他们放在类实现的开始位置

        对某个类扩展功能时优先使用增加类别。


5.标准命名规范

http://blog.csdn.net/bill1315/article/details/1698202

命名方法:
(1),骆驼(Camel)命名法:第一个字母小写,随后的每个单词的第一个字母大写。如:studentName
(2),帕斯卡(Pascal)命名法:每一个单词的第一个字母都大写。如:StudentName
(3),匈牙利命名法:加前缀。如btnName,txtName.


6.对网络请求对象的处理要点:

  引用request句柄,

  在请求结束后request=nil,

  在析构中和其它需要的地方 request.delegate=nil; [request cancel]; request=nil;


7.防御式编程的要求使用NSAssert语句来保证一些必不可错的错误发生,比如参数属于正确的类。

 

03-10 732
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值