微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Objective-C 的Cocoa风格:第一部分

 

Objective-C 的Cocoa风格:第一部分

    概括地说就是Cocoa和Objective-C看起来应该是什么样的?
    一旦了解了Objective-C和Cocoa的基础你就可以开始写些代码了。但是Objective-C的命名和格式规则不同于传统的C、C++以及Java程序。
    Apple为了实现最大的清晰性和与框架的集成性订立利用一系列的指导原则。此外还有Cocoa开发人员经常使用的未成文规则。 
    从根本上说在Objective-C和Cocoa可以找到Apple为最终用户设计的产品中的人的因素。
    第 1部分: 类、变量、访问函数、通用方法和缩写的命名基础。
   第 2部分:关于方法名、全局符号、id类型、方法参数等等的更详细的介绍。


将想法转成命名
    在软件开发的早期,一般程序都由少得多的代码组成。通过更小的方法和更少的变量就可以理解像cp的意思是字符指针,fread表示从文件读数据的函数之类的。由于终端屏幕上的空间有限,较短名字就比较合理。


    更新点的程序就有更多的变量和函数在这样的环境下,短名字变得很模糊,从而导致了其成为有很多bug的代码。Xcode和其他编辑器会为你自动补全长的名字。 
    Cocoa强烈鼓励使用富有表达性、清晰、无歧义的名字。看看下表给出的一些类。你可以从它们的名字就可以知道些它们的用途。

Cocoa类
NSPasteboard
NSCell
NSComboBox
NSComboBoxCell
NSMenuItem
NSMenuItemCell


    同时也注意下有些是其他类名合成的。比如NSMenuItemCell就意味着一个菜单项使用的单元格。
命名一致性不是加分,而是Cocoa程序员一项基本的要求。请记住由于你阅读的代码要远多于写的代码,请在命名上花点时间。


类名
    不论是Cocoa标准库的还是你自定义的,类名都必须是首字母大写的。
    Objective-C 没有命名空间,所以请在你的类名前加个前缀。这可以避免 “命名空间冲突”,即相同名字的两段代码实现不同功能的情况。Cocoa Dev Central制作的类可能就会以"CDC"打头。
    如果你继承一个标准的Cocoa类,最好可以在父类名字前加入你的前缀,比如CDCTableView。
    由于Cocoa是基于NeXTSTEP开发框架这一历史原因大多数标准Cocoa类都是NS打头的。


标准类
Nsstring
NSMutableArray
NSDictionary
自定义
CDCRecipient
CDCEmail
CDCEmailAttachment
自定义继承子类
CDCTableView
CDCOutlineView
CDCArrayController


变量名
    变量名的首字母小写,之间出现的新单词首字母大写。
 

 
 
  1. Nsstring * streetAddress  = @"1 Infinite Loop";  
  2. Nsstring * cityName       = @"Cupertino";  
  3. Nsstring * countyName     = @"Santa Clara"


    正如之前讨论的,Cocoa强烈推荐清晰、明显的变量名,而不是简短的。模糊通常会导致bug,所以还是明确点。

 
 
  1. //正确  
  2. Nsstring       * hostName;  
  3. NSNumber       * ipAddress;  
  4. NSArray        * accounts;  
  5.  
  6. //不正确  
  7. Nsstring       * HST_NM;      // 所有都大写而且太简短all caps and too terse  
  8. NSNumber       * theip;       // 一个单词还是一个缩写呢a word or abbreviation?  
  9. NSMutableArray * nsma;        // 太模糊了completely ambiguous  


    C以及其他语言的变量命名语法在Objective-C中也适用。变量不能以数字、空格以及除下划线之外的特殊字符打头。
    Apple不鼓励使用下划线作为私有实例变量的前缀。

 
 
  1. Nsstring * name    // 正确!  
  2. Nsstring * _name   // _不正确_ 


    实际上,私有前缀这个想法是没有必要的,因为Cocoa中几乎所有的实例变量都是受保护的。
 

变量名:表明类型
    在实践中,变量名通常不会表明自己的类型是Nsstring、NSArray、NSNumber或者BOOL的。

 
 
  1. //正确  
  2. Nsstring       *accountName;  
  3. NSMutableArray *mailBoxes;  
  4. NSArray        *defaultHeaders;  
  5. BOOL             userInputWasUpdated;  
  6.  
  7. //可以,但不是很理想  
  8. Nsstring       *accountNameString;  
  9. NSMutableArray *mailBoxArray;  
  10. NSArray        *defaultHeadersArray;  
  11. BOOL            userInputWasUpdatedBOOL;  


    如果变量不是上述类型之一的,必须在名字反映这些。还有些变量你仅仅需要一个实例。在这样情况下,就只需要根据类名进行命名。字体管理器就是这方面的一个很好例子。

 
 
  1. //何时要表明类型
  2. NSImage             *previewPaneImage;  // 无需说明  
  3. nsprogressIndicator *uploadindicator;   // 显示上传进度  
  4. NSFontManager       *fontManager;       // 只有一个,所以使用基本名字就可以 


    大多数情况下,复数(比如mailBoxes)表示一个NSArray or NSSet 。没有必要在名字中指明“可变的”。
如果复数不是一个NSArray或NSSet,如下的指定也是合理的。

 
 
  1. NSDictionary *keyedAccountNames;  
  2. NSDictionary *messageDictionary;  
  3. NSIndexSet   *selectedMailBoxesIndexSet; 


    但必须承认是,这是一个灰色区域。


方法

    方法可能是我们可以讨论的最重要的一个话题。大多数面向对象语言有如下语法:

 
 
  1. //其他语言的例子
  2. object.begin(resource);  
  3. object.processData(resource, data, true);  
  4. object.end(true); 


    这些方法这第一次写的时候很容易,但实际行为就不是很清晰。但周围有大量代码的情况下更是一个问题。
Cocoa程序员从最终出发考虑,根据在实际使用中方法的模样是来选择方法名。比如要写一个内存上文件对象到硬盘上。在一些语言中会是这样的:

 
 
  1. fileWrapper.write(path, truetrue); 


    在Cocoa/Objective-C则是:

 
 
  1. [fileWrapper writ@R_404_6440@File: path atomically: YES updateFilenames: YES];  


    在创建一个方法的时候问问自己它的行为是否从名字就可以仅清晰地知道,尤其是在被成千上万行的代码包围的时候。
    程序员要阅读的代码要比写的多得多,所以Objective-C 的设计就是更利用阅读。将消息读成一个语句是来检查方法名字的一个好的途径:

 
 
  1. //"通过该应用打开文件并停用"  
  2. [finder openFile: mailing withApplication: @"MailDrop" andDeactivate: YES]; 

这个消息被送到了NSWorkspace (也被称为 Finder),它显然可以通过“语句”测试。

方法名:访问方法
    和很多其他语言不一样的是,Objective-C不鼓励使用"get"作为简单访问函数的前缀。实例变量和方法可以有相同的名字,所以可以充分利用这个。

 
 
  1. //正确!  
  2. - (Nsstring *) name;  
  3. - (Nsstring *) color;  
  4.  
  5. name  = [object name];  
  6. color = [object color];  
  7.  
  8. //不正确  
  9. - (Nsstring *) getName;  
  10. - (NSColor  *) getColor;  
  11.  
  12. name  = [object getName];  
  13. color = [object getColor];  


    不过"get"前缀可以用在通过内存地址间接返回值的场合。
    使用"get"前缀的场合

 
 
  1. // 将对象从NSArray拷贝到buffer  
  2. id *buffer = (id *) malloc(sizeof(id) * [array count]);  
  3. [array g@R_404_6440@bjects: buffer];  
  4. //(如果你不知道malloc做什么也没关系。)   


    "set"前缀就需要在设定函数中都使用:

 
 
  1. [object setName:  name];  
  2. [object setColor: color]; 


形容词
    不是所有的访问函数都返回诸如名字、日期、高度等等的值。一些会表示对象的特殊属性。它们通常使用布尔值表示。
    比如"selectable"。在Objective-C该键值的查询方法叫做-isSelectable,设定方法则是-setSelectable:
 

 
 
  1. BOOL selectable = [textView isSelectable];  
  2. BOOL editable   = [textView isEditable];  
  3.  
  4. [textView setSelectable: YES];    // 没有"is"  
  5. [textView setEditable:   YES];    // 没有"is"  
  6.  
  7. //如果textview可编辑  
  8.  
  9. if ([textView isEditable])  
  10.       [textView setEditable: NO];  


    需要记住的是根据这些规则命名访问方法不仅仅是个清晰和美感的问题。Cocoa。Cocoa很多奇妙的功能都是通过键-值-编码(KVC key-value coding)实现的,KVC有赖于合理命名的访问函数


缩写
    你可能注意到了总体原则就是完全拼写以避免混淆。但是有时一些公认的缩写如果完全拼写出来不仅无益而且可能导致混淆。
    如下缩写节选自合适缩写的完全列表: 
     int     max     min     TIFF    HTTP    URL     HTML     PDF
     rect    temp    info    JPG     FTP     RTF     XML      ASCII
 

预编译常量/宏
和ANSI C类似,预编译定义必须全部大写。

 
 
  1. #define MAX_ENTRIES 20  
  2. #ifdef  ENABLE_BINDINGS_SUPPORT 


小结

    到目前为止你已经学习到了一些基础知识,现在可以看看第二部分了。该部分会详细介绍方法命名、全局函数和符号、利用id的动态类型、命名方法变量及其更多。
    老规矩,如果对本教材有任何想法请告诉我们。


原文链接http://cocoadevcentral.com/articles/000082.php

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐