`
dcj3sjt126com
  • 浏览: 1825391 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Object-C编码规范

 
阅读更多
  • Object-C编码规范

    参考资料:
    • Apple: Coding Guidelines for Cocoa
    • Google: Objective-C Style Guide
    • Three20: Source code style guildelines
    正文:
    • 格式化代码
    ◦ 指针“*”号的位置
    ▪ 如:NSString *varName;
    ◦ 空格 VS tabs
    ▪ 只允许使用空格,将编辑器设置为1个TAB = 2个字符缩进
    ◦ 每行的长度
    ▪ 每行最多不得超过100个字符
    ▪ 以15寸Macbook Pro的大小,每行100个字符时能最大化地同时容下编辑器和iPhone模拟器
    ▪ Google的80字符的标准有点少,这导致过于频繁的换行(Objectve-C的代码一般都很长)
    ▪ 通过 “Xcode => Preferences => TextEditing => 勾选Show Page Guide / 输入
    100 => OK” 来设置提醒
    ◦ 方法的声明和定义
    ▪ 在 – OR + 和返回值之间留1个空格,方法名和第一个参数间不留空格。如:
    - (void)doSomethingWithString:(NSString *)theString {

    }
    ▪ 当参数过长时,每个参数占用一行,以冒号对齐。如:
    - (void)doSomethingWith:(GTMFoo *)theFoo
    rect:(NSRect)theRect
    interval:(float)theInterval {

    }
    ▪ 如果方法名比参数名短,每个参数占用一行,至少缩进4个字符,且为垂直对齐(而非使用冒号
    对齐)。如:
    - (void)short:(GTMFoo *)theFoo
    longKeyword:(NSRect)theRect
    evenLongerKeyword:(float)theInterval {

    }
    ◦ 方法的调用
    ▪ 调用方法沿用声明方法的习惯。例外:如果给定源文件已经遵从某种习惯,继续遵从那种习惯。
    ▪ 所有参数应在同一行中,或者每个参数占用一行且使用冒号对齐。如:
    [myObject doFooWith:arg1 name:arg2 error:arg3];

    [myObject doFooWith:arg1
    name:arg2
    error:arg3];
    ▪ 和方法的声明一样,如果无法使用冒号对齐时,每个参数一行、缩进4个字符、垂直对其(而非
    使用冒号对齐)。如:
    [myObj short:arg1
    longKeyword:arg2
    evenLongerKeyword:arg3];
    ◦ @public 和 @private
    ▪ @public 和 @private使用单独一行,且缩进1个字符
    ◦ Protocals
    ▪ 类型标示符、代理名称、尖括号间不留空格。
    ▪ 该规则同样适用于:类声明、实例变量和方法声明。如:
    @interface MyProtocoledClass : NSObject<NSWindowDelegate> {
    @private
    id<MyFancyDelegate> _delegate;
    }
    - (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
    @end
    ▪ 如果类声明中包含多个protocal,每个protocal占用一行,缩进2个字符。如:
    @interface CustomViewController : ViewController<
    AbcDelegate,
    DefDelegate
    > {

    }
    • 命名
    ◦ 类名
    ▪ 类名(及其category name 和 protocal name)的首字母大写,写使用首字母大写的形式
    分割单词
    ▪ 在面向特定应用的代码中,类名应尽量避免使用前缀,每个类都使用相同的前缀影响可读性。
    ▪ 在面向多应用的代码中,推荐使用前缀。如:GTMSendMessage
    ◦ Category Name
    ▪ 待完善
    ◦ 方法名
    ▪ 方法名的首字母小写,且使用首字母大写的形式分割单词。方法的参数使用相同的规则。
    ▪ 方法名+参数应尽量读起来像一句话(如:)。在这里查看苹果对方法命名的规范。
    ▪ getter的方法名和变量名应相同。不允许使用“get”前缀。如:
    - (id) getDelegate; // 禁止
    - (id)delegate; // 对头
    ▪ 本规则仅针对Objective-C代码,C++代码使用C++的习惯
    ◦ 变量名
    ▪ 变量名应使用容易意会的应用全称,且首字母小写,且使用首字母大写的形式分割单词
    ▪ 成员变量使用“_”作为前缀(如:“NSString *_varName;”。虽然这与苹果的标准(使
    用“_”作为后缀)相冲突,但基于以下原因,仍使用“_”作为前缀。
    ▪ 使用“_”作为前缀,更容易在有代码自动补全功能的IDE中区分“属性
    (self.userInfo)”和“成员变量(_userInfo)”
    ▪ 常量(#define, enums, const等)使用小写“k”作为前缀,首字母大写来分割单词。如:
    kInvalidHandle
    • 注释
    ◦ 待完善
    • Cocoa 和 Objective-C特有的规则
    ◦ 成员变量使用 @private。如:
    @interface MyClass : NSObject {
    @private
    id _myInstanceVariable;
    }
    // public accessors, setter takes ownership
    - (id)myInstanceVariable;
    - (void)setMyInstanceVariable:(id)theVar;
    @end
    ◦ Indentify Designated Initializer
    ▪ 待完善
    ◦ Override Desingated Initializer
    ▪ 待完善
    ◦ 初始化
    ▪ 在初始化方法中,不要将变量初始化为“0”或“nil”,那是多余的
    ▪ 内存中所有的新创建的对象(isa除外)都是0,所以不需要重复初始化为“0”或“nil”
    ◦ 避免显式的调用 +new 方法
    ▪ 禁止直接调用 NSObject 的类方法 +new,也不要在子类中重载它。使用alloc和init方法
    ◦ 保持公共API的简洁性
    ▪ 待完善
    ◦ #import VS #include
    ▪ 使用 #import 引入Ojbective-C和Ojbective-C++头文件,使用 #include 引入C和C++头
    文件
    ◦ import根框架(root frameworks),而非各单个文件
    ▪ 虽然有时我们仅需要框架(如Cocoa 或 Foundation)的某几个头文件,但引入根文件编译
    器会运行的更快。因为根框架(root frameworks)一般会预编译,所以加载会更快。再次强
    调:使用 #import 而非 #include 来引入Objective-C框架。如:
    #import <Foundation/NSArray.h> // 禁止
    #import <Foundation/NSString.h>

    #import <Foundation/Foundation.h> // 对头
    ◦ 创建对象时尽量使用autorelease
    ▪ 创建临时对象时,尽量同时在同一行中 autorelease 掉,而非使用单独的 release 语句
    ▪ 虽然这样会稍微有点慢,但这样可以阻止因为提前 return 或其他意外情况导致的内存泄露。
    通盘来看这是值得的。如:
    // 避免这样使用(除非有性能的考虑)
    MyController* controller = [[MyController alloc] init];
    // … 这里的代码可能会提前return …
    [controller release];
    // 这样更好
    MyController* controller = [[[MyController alloc] init] autorelease];
    ◦ 先autorelease,再retain
    ▪ 在为对象赋值时,遵从“先autorelease,再retain”
    ▪ 在将一个新创建的对象赋给变量时,要先将旧对象release掉,否则会内存泄露。市面上有很
    多方法来handle这种情况,这里选择“先autorelease,再retain”的方法,这种方法不易引
    入error。注意:在循环中这种方法会“填满”autorelease pool,稍稍影响效率,但是
    Google和我(  )认为这个代价是可以接受的。如:
    - (void)setFoo:(GMFoo *)aFoo {
    [foo_ autorelease]; // 如果foo_和aFoo是同一个对象(foo_ == aFoo),
    dealloc不会被调用
    foo_ = [aFoo retain];
    }
    ◦ dealloc的顺序要与变量声明的顺序相同
    ▪ 这有利于review代码
    ▪ 如果dealloc中调用其他方法来release变量,将被release的变量以注释的形式标注清楚
    ◦ NSString的属性的setter使用“copy”
    ▪ 禁止使用retain,以防止意外的修改了NSString变量的值。如:
    - (void)setFoo:(NSString *)aFoo {
    [foo_ autorelease];
    foo_ = [aFoo copy];
    }

    @property (nonatomic, copy) NSString *aString;
    ◦ 避免抛出异常(Throwing Exceptions)
    ▪ 待完善
    ◦ 对 nil 的检查
    ▪ 仅在有业务逻辑需求时检查 nil,而非为了防止崩溃
    ▪ 向 nil 发送消息不会导致系统崩溃,Objective-C运行时负责处理。
    ◦ BOOL陷阱
    ▪ 将int值转换为BOOL时应特别小心。避免直接和YES比较
    ▪ Objective-C中,BOOL被定义为unsigned char,这意味着除了 YES (1) 和 NO (0)外它
    还可以是其他值。禁止将int直接转换(cast or convert)为BOOL。
    ▪ 常见的错误包括:将数组的大小、指针值或位运算符的结果转换(cast or convert)为
    BOOL,因为该BOOL值的结果取决于整型值的最后一位
    ▪ 将整型值转换为BOOL的方法:使用三元运算符返回YES / NO,或使用位运算符(&&, ||, !)
    ▪ BOOL、_Bool和bool之间的转换是安全的,但是BOOL和Boolean间的转换不是安全的,所以
    将Boolean看成整型值。
    ▪ 在Objective-C中,只允许使用BOOL
    ▪ 如:
    // 禁止
    - (BOOL)isBold {
    return [self fontTraits] & NSFontBoldTrait;
    }
    - (BOOL)isValid {
    return [self stringValue];
    }
    // 对头
    - (BOOL)isBold {
    return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
    }
    - (BOOL)isValid {
    return [self stringValue] != nil;
    }
    - (BOOL)isEnabled {
    return [self isValid] && [self isBold];
    }
    ▪ 禁止直接将BOOL和YES/NO比较,如:
    // 禁止
    BOOL great = [foo isGreat];
    if (great == YES)

    // 对头
    BOOL great = [foo isGreat];
    if (great)

    ◦ 属性
    ▪ 命名:与去掉“_”前缀的成员变量相同,使用@synthesize将二者联系起来。如:
    // abcd.h
    @interface MyClass : NSObject {
    @private
    NSString *_name;
    }
    @property (copy, nonatomic) NSString *name;
    @end
    // abcd.m
    @implementation MyClass
    @synthesize name = _name;
    @end
    ▪ 位置:属性的声明紧随成员变量块之后,中间空一行,无缩进。如上例所示
    ▪ 严把权限:对不需要外部修改的属性使用readonly
    ▪ NSString使用copy而非retain
    ▪ CFType使用@dynamic, 禁止使用@synthesize
    ▪ 除非必须,使用nonatomic
    • Cocoa Pattern
    ◦ Delegate Pattern(委托)
    ▪ delegate对象使用assign,禁止使用retain。因为retain会导致循环索引导致内存泄露,
    并且此类型的内存泄露无法被Instrument发现,极难调试
    ▪ 成员变量命名为_delegate,属性名为delegate
    ◦ Model/View/Controller
    ▪ Model和View分离
    ▪ 不多解释
    ▪ Controller独立于View和Controller
    ▪ 不要在与view相关的类中添加过多的业务逻辑代码,这让代码的可重用性很差
    ▪ Controller负责业务逻辑代码,且Controller的代码与view尽量无关
    ▪ 使用 @protocal 定义回调APIs,如果并非所有方法都是必须的,使用 @optional 标示
    • 其他
    ◦ init方法和dealloc方法是是最常用的方法,所以将他们放在类实现的开始位置
    ◦ 使用空格将相同的变量、属性对齐,使用换行分组
分享到:
评论

相关推荐

    一般Object-C的编码规范指南

    一份用于ios中object-C的编程规范指南,新手可以看看,养成自己的代码习惯

    Object C programing guide

    学习Object C很好的资料,基本概念,编码规范,是学习iPhone开发很好的参考资料

    json-c-0.7.rar_c json_json c_json 数据 格式_json-c vc_xml-json-c

    JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。[编辑本段]JSON与XML的比较  ◆可读性  ...

    阿里云开放存储服务的C语言SDKOSSC.zip

    OSSC完全采用C语言开发,并实现了类似面向对象的调用方式,遵循了良好的编码规范,目前OSSC除了提供了OSS开放接口文档中所描述的四大类功能外(Bucket 操作、Object 操作、Multipart Upload操作、Object Group 操作...

    JPJson:Objective-C 和 C++ 的 JSON 框架

    基本功能该实现严格符合 RFC 4627 中定义的规范、“JavaScript Object Notation (JSON)”以及 Unicode 标准版本 6.0 中发布的规范和指南。 “JSON 解析器”可以读取任何 Unicode 编码方案的 JSON 文本,即 UTF-8、...

    最新中农大线上作业Java语言与面向对象程序设计A-F(1).doc

    中农大线上作业Java语言与面向对象程序设计A-F(1...描述和表示 参考答案:C 您的答案:B 20、所谓面向对象程序设计语言(Object-Oriented Programming Language)简称"( )"。 A.POOL B.OODL C.OOPL D.MUL 参考

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    Project-Setting-Link中的Object/Library Modules: kernel32.lib user32.lib ... xxx.lib之类的内容最后增加: osipparser2.lib 保存工程后再次编译,即可成功编译...

    代码语法错误分析工具pclint8.0

    并提供编码规则检查,规范软件人员的编码行为。 由于PC-LINT对于一般程序员来说可能比较陌生,有好多人安装了也不知道怎样配置和使用。 下面我就根据自己的安装和配置心得对PC-Lint的安装、配置及使用进行下详细...

    json:Ruby的JSON实现

    Ruby的JSON实现 描述 这是根据RFC 7159 的JSON规范的实现。 从版本1.0.0开始,将提供两个变体: ... 要对未经UTF-8编码的原始二进制字符串进行编码,请使用String的to_json_raw_object方法(该方法生成一个

    ExtAspNet v2.2.1 (2009-4-1) 值得一看

    -修正Alert消息中引号未编码导致的JS错误(feedback:sun1299shine)。 +集成extjs3.0.3。 -修正弹出对话框的宽度计算错误(会保持最小的状态)。 -增加新的皮肤Gray。 -为示例工程添加改变语言和皮肤的下拉列表。...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle 甲骨文 获得最高认证级别的ISO标准安全认证,性能最高, 保持开放平台下的TPC-D和TPC-C的世界记录。但价格不菲 大型企业 db2 IBM DB2在企业级的应用最为广泛, 在全球的500家最大的企业中,几乎85%以上用DB2...

    XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解

    W3C组织正在研究一种名为RDF(Resource Description Framework)的metadata处理方法,可以自动交换信息,W3C宣称,使用RDF配合数字签名,将使网络中存在"真实可信"的电子商务。 六.显示 单独用XMl不能显示页面,...

    JAVA_API1.6文档(中文)

    java.nio.charset 定义用来在字节和 Unicode 字符之间转换的 charset、解码器和编码器。 java.nio.charset.spi java.nio.charset 包的服务提供者类。 java.rmi 提供 RMI 包。 java.rmi.activation 为 RMI 对象...

    Thinking in Java(中文版 由yyc,spirit整理).chm

    12.2.5 Object.clone()的效果 12.2.6 克隆合成对象 12.2.7 用Vector进行深层复制 12.2.8 通过序列化进行深层复制 12.2.9 使克隆具有更大的深度 12.2.10 为什么有这个奇怪的设计 12.3 克隆的控制 12.3.1 副本构建器 ...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    12.2.5 Object.clone()的效果 12.2.6 克隆合成对象 12.2.7 用Vector进行深层复制 12.2.8 通过序列化进行深层复制 12.2.9 使克隆具有更大的深度 12.2.10 为什么有这个奇怪的设计 12.3 克隆的控制 12.3.1 副本构建器 ...

    day023-xml解析笔记和代码.rar

    O Object 对象(Java对象) : 把xml文件封装成Java对象 M Model 模型 解析过程中用到的类: Document Node(节点) Element (元素) Attribute(属性) - Attr Text(文本) ...

    超级有影响力霸气的Java面试题大全文档

     Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,...

    java api最新7.0

    java.nio.charset 定义用来在字节和 Unicode 字符之间转换的 charset、解码器和编码器。 java.nio.charset.spi java.nio.charset 包的服务提供者类。 java.rmi 提供 RMI 包。 java.rmi.activation 为 RMI 对象提供...

    java源码包---java 源码 大量 实例

    本规范尝试满足大型主机、微型主机、个人工作站、和TACs 的不同需求。例如,容易实现协议的设计。 Java EJB中有、无状态SessionBean的两个例子 两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取...

Global site tag (gtag.js) - Google Analytics