Objective-C编程中语句和变量的一些编写规范建议

语句
条件语句

条件语句体应该总被大括号包围。只有一行代码最好也加上,否则会带来安全隐患。

代码如下:

// 推荐
if (!error) {
    return success;
}

// 不推荐
if (!error)
    return success;

if (!error) return success;

尤达表达式(Yoda)

不要使用尤达表达式。(名字起源于星球大战中尤达大师的讲话方式,总是用倒装的语序)

代码如下:

// 推荐
if ([myValue isEqual:@42]) { ...

// 不推荐
if ([@42 isEqual:myValue]) { ...

nil和BOOL的检查

一些人喜欢用这样的方式来检查nil:

代码如下:

if (nil == myValue) { ...

这样做可以避开少些一个"=“的错误,因为一旦少写一个”=“,那么nil是不能被赋值的,编译器会报错。

但是前面提到,最好不要使用尤达表达式。所以更好的解决方法是用”!”来完成nil和BOOL的检查。

代码如下:

// 推荐
if (someObject) { ...
if (![someObject boolValue]) { ...
if (!someObject) { ...

// 不推荐
if (someObject == YES) { ... // Wrong
if (myRawValue == YES) { ... // Never do this.
if ([someObject boolValue] == NO) { ...

不要嵌套多个if语句

不要嵌套多个if语句,而是使用多个return来避免增加复杂度,并提高代码可读性。

也就是说,在一个方法中,重要的部分尽量不要放在if语句中,而是将”其它情况”放在if中。

代码如下:

// 推荐
- (void)someMethod {
  if (![someOther boolValue]) {
      return;
  }

//Do something important
}

// 不推荐
- (void)someMethod {
  if ([someOther boolValue]) {
    //Do something important
  }
}

复杂的表达式

当一个判断条件很复杂时,应该将它们提取出来赋值给一个BOOL变量。

代码如下:

BOOL nameContainsSwift  = [sessionName containsString:@"Swift"];
BOOL isCurrentYear      = [sessionDateCompontents year] == 2014;
BOOL isSwiftSession     = nameContainsSwift && isCurrentYear;

if (isSwiftSession) {
    // Do something very cool
}

三元运算符

三元运算符要保证可读性。

代码如下:

// 推荐
result = a > b ? x : y;

// 不推荐
result = a > b ? x = c > d ? c : d : y;

当三元运算符的第二个参数(if 分支)返回和条件语句中已经检查的对象一样的对象的时候,下面的表达方式更灵巧:

代码如下:

// 推荐
result = object ? : [self createObject];

// 不推荐
result = object ? object : [self createObject];

错误处理

有些方法通通过参数返回 error 的引用,使用这样的方法时应当检查方法的返回值,而非 error 的引用。

代码如下:

// 推荐
NSError *error = nil;
if (![self trySomethingWithError:&error]) {
    // Handle Error
}

switch语句中的case,如果只有一行代码可以不必加上大括号,但是多行需要加上。

代码如下:

switch (condition) {
    case 1:
        // ...
        break;
    case 2: {
        // ...
        // Multi-line example using braces
        break;
       }
    case 3:
        // ...
        break;
    default:
        // ...
        break;
}

枚举类型

使用NS_ENUM()这个宏来定义枚举,它有更强大的的类型检查和代码补全。

代码如下:

typedef NS_ENUM(NSUInteger, ZOCMachineState) {
    ZOCMachineStateNone,
    ZOCMachineStateIdle,
    ZOCMachineStateRunning,
    ZOCMachineStatePaused
};

变量
尽量使用长的、描述性的方法和变量名。

代码如下:

// 推荐
UIButton *settingsButton;

// 不推荐
UIButton *setBut;

常量应该以驼峰法命名,并以相关类名作为前缀。

代码如下:

// 推荐
static const NSTimeInterval ZOCSignInViewControllerFadeOutAnimationDuration = 0.4;

// 不推荐
static const NSTimeInterval fadeOutTime = 0.4;

推荐使用常量来代替字符串字面值和数字。可以方便复用,快速修改。

常量应该用static声明为静态常量,而不要用#define,除非它明确作为宏来使用。

代码如下:

// 推荐
static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";

static const CGFloat ZOCImageThumbnailHeight = 50.0f;

// 不推荐
#define CompanyName @"Apple Inc."
#define magicNumber 42

常量如果需要暴露给外部,那么要在头文件中以这样的形式:

代码如下:

extern NSString *const ZOCCacheControllerDidClearCacheNotification;

并在实现文件中为它赋值。

只有公有的常量才需要添加命名空间作为前缀。尽管实现文件中私有常量的命名可以遵循另外一种模式,你仍旧可以遵循这个规则。

方法名与方法类型(-/+符号)间应加上一个空格。

方法段间也应该以空格间隔。

参数前应该有一个描述性的关键词。

尽可能少用”and”这个词,它不应该用来阐明有多个参数。

代码如下:

// 推荐
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

// 不推荐
- (void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height;  // Never do this.

使用字面值来创建不可变的NSString,NSDictionary,NSArray和NSNumber对象。

用这种方式,注意不要将nil放在NSArray和NSDictionary里,这样会导致崩溃。

代码如下:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;

不要这样:

代码如下:

NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018];

避免这样的方式创建可变数组:

代码如下:

NSMutableArray *aMutableArray = [@[] mutableCopy];

这样的方式,在效率和可读性上都存在问题。

效率:一个不必要的不可变数组被创建后马上被废弃,并没有必要。

可读性:可读性并不好。

(0)

相关推荐

  • 举例讲解Objective-C中@property属性的用法

    学过c/c++的朋友都知道,我们定义struct/class的时候,如果把访问限定符(public,protected,private)设置为public的话,那么我们是可以直接用.号来访问它内部的数据成员的.比如 //in Test.h class Test { public: int i; float f; }; 我在main函数里面是可以通过下面的方式来使用这个类的:(注意,如果在main函数里面使用此类,除了要包含头文件以外,最重要的是记得把main.m改成main.mm,否则会报一些奇

  • 详解Objective-C编程中对设计模式中适的配器模式的使用

    引言 在项目开发中,有时候会遇到这样的一种情景:需要使用以前开发的"一些现存的对象",但是新环境中要求的接口是这些现存对象所不满足的.怎样应对这种迁移的需求?使得可以复用这些对象,以满足新的应用环境,这就是适配器(Adapter)所要解决的问题. 定义 "将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作." 最初的定义出现于<设计模式>(Addison-Wesley,1994). 这个定义应该

  • 理解Objective-C的变量以及面相对象的继承特性

    OC点语法和变量作用域 一.点语法 (一)认识点语法 声明一个Person类: 复制代码 代码如下: #import <Foundation/Foundation.h> @interface Person : NSObject {     int _age;//默认为@protected } - (void)setAge:(int)age; - (int)age; @end Person类的实现: 复制代码 代码如下: #import "Person.h" @impleme

  • 浅析Objective-C中分类Category的使用

    无论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎么扩展现有的类呢?当然,继承是个不错的选择.但是Objective-C提供了一种特别的方式来扩展类,叫Catagory,可以动态的为已经存在的类添加新的行为.这样可以保证类的原原来的基础上,较小的改动就可以增加需要的功能.使用Category对类进行扩展时,不需要访问其源代码,也不需要创建子类,这样我们可以扩展系统提供的类.Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中. 使用Ob

  • 详解Objective-C设计模式编程中对备忘录模式的运用

    基本理解 这个模式有三个关键角色:原发器(Originator).备忘录(Memento).看管人(caretaker).三者的基本关系是:原发器创建一个包含其状态的备忘录,并传给看管人.看管人不知道如何与备忘录交互,但会把备忘录放在一个安全之处保管好. 备忘录(Memento):在 不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象回复到原先保存的状态. Originator(发起人):负责创建一个备忘录,用以记录当前时刻它的内部状态,并且可使用恢

  • 以实例讲解Objective-C中的KVO与KVC机制

    KVO实例浅析 最近遇到个问题,在处理项目中一个评论界面时,因为直接用的是UIWebView展示评论列表,结果取到的页面上下都有一段CGSize为(320,65)的乱七八糟的广告,十分碍眼.头部广告因很方便的在头部坐标贴上自己的logo解决了,但是尾部的,因为每个页面的评论长短不一,坐标也就不一样,这样就不能给定死坐标去贴logo,思前想后,通过KVO很好的解决了这个问题. @KVO概述: KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会

  • 简介Objective-C解析XML与JSON数据格式的方法

    解析XML 本文以解析本地XML为例,网络获取到的返回值只需转换成NSData型,解析是同理 需要解析的xml文件如下,users.xml <?xml version="1.0" encoding="UTF-8"?> <AllUsers> <message>用户信息</message> <user> <name>芳仔小脚印</name> <age>10</age&g

  • Objective-C的NSOperation多线程类基本使用指南

    NSOperation 一.NSOperation 1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用它的子类,使用NSOperation子类的方式有2种: 1> Foundation框架提供了两个具体子类直接供我们使用:NSInvocationOperation和NSBlockOperation 2> 自定义子类继承NSOperation,实现内部相应的方法 2.执行操作

  • 简单讲解Objective-C的基本特性及其内存管理方式

    一.OC简介 Oc语言在c语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,在OC代码中,可以混用c,甚至是c++代码. 可以使用OC开发mac osx平台和ios平台的应用程序. 拓展名:c语言-.c  OC语言.-m  兼容C++.-mm 注:其实c语言和oc甚至任何一门语言都只是我们为了实现一些功能,达到一些效果而采用的工具,抛开语法的差别外,我想最重要的应该是在解决问题的时候考虑的角度和方法不一样而已,然而这也构成了学习一门语言的重要性. 二.语法预览 (1)关键字 基本上所有

  • Objective-C中编程中一些推荐的书写规范小结

    一.类 1. 类名 类名应该以三个大写字母作为前缀(双字母前缀为Apple的类预留) 不仅仅是类,公开的常量.Protocol等的前缀都为相同的三个大写字母. 当你创建一个子类的时候,你应该把说明性的部分放在前缀和父类名的中间. 例如: 如果你有一个 ZOCNetworkClient 类,子类的名字会是ZOCTwitterNetworkClient (注意 "Twitter" 在 "ZOC" 和 "NetworkClient" 之间); 按照这个

随机推荐