第3条:多用字面量语法,少用与之等价的方法(2)

http://book.51cto.com/art/201403/432131.htm

第3条:多用字面量语法,少用与之等价的方法(2)

在改用字面量语法来创建数组时就会遇到这个问题。下面这段代码分别以两种语法创建数组:

 
 
  1. id object1 = /* ... */;  
  2. id object2 = /* ... */;  
  3. id object3 = /* ... */;  
  4.  
  5. NSArray *arrayA = [NSArray array WithObjects:  
  6.                        object1, object2, object3, nil];  
  7. NSArray *arrayB = @[object1, object2, object3]; 

大家想想:如果object1与object3都指向了有效的Objective-C对象,而object2是nil,那么会出现什么情况呢?按字面量语法创建数组arrayB时会抛出异常。arrayA虽然能创建出来,但是其中却只含有object1一个对象。原因在于,“arrayWithObjects:”方法会依次处理各个参数,直到发现nil为止,由于object2是nil,所以该方法会提前结束。

这个微妙的差别表明,使用字面量语法更为安全。抛出异常令应用程序终止执行,这比创建好数组之后才发现元素个数少了要好。向数组中插入nil通常说明程序有错,而通过异常可以更快地发现这个错误。

字面量字典

“字典”(Dictionary)是一种映射型数据结构,可向其中添加键值对。与数组一样,Objective-C代码也经常用到字典。其创建方式如下:

 
 
  1. NSDictionary *personData =  
  2.     [NSDictionarydictionaryWithObjectsAndKeys:  
  3.         @"Matt", @"firstName",  
  4.         @"Galloway", @"lastName",  
  5.         [NSNumber numberWithInt:28], @"age",  
  6.         nil]; 

这样写令人困惑,因为其顺序是<对象>,<键>,<对象>,<键>。这与通常理解的顺序相反,我们一般认为是把“键”映射到“对象”。因此,这种写法不容易读懂。如果改用字面量语法,就清晰多了:

 
 
  1. NSDictionary *personData =  
  2.     @{@"firstName" : @"Matt",  
  3.       @"lastName" : @"Galloway",  
  4.       @"age" : @28}; 

上面这种写法更简明,而且键出现在对象之前,理解起来较顺畅。此范例代码还说明了使用字面量数值的好处。字典中的对象和键必须都是Objective-C对象,所以不能把整数28直接放进去,而要将其封装在NSNumber实例中才行。使用字面量语法很容易就能做到这一点,只需给数字前加一个@字符即可。

与数组一样,用字面量语法创建字典时也有个问题,那就是一旦有值为nil,便会抛出异常。不过基于同样的原因,这也是个好事。假如在创建字典时不小心用了空值对象,那么“dictionaryWithObjectsAndKeys:”方法就会在首个nil之前停下,并抛出异常,这有助于查错。

字典也可以像数组那样用字面量语法访问。按照特定键访问其值的传统做法是:

 
 
  1. NSString *lastName = [personData objectForKey:@"lastName"]; 

与之等效的字面量语法则是:

 
 
  1. NSString *lastName = personData[@"lastName"]; 

这样写也省去了冗赘的语法,令此行代码简单易读。

可变数组与字典

通过取下标操作,可以访问数组中某个下标或字典中某个键所对应的元素。如果数组与字典对象是可变的(mutable),那么也能通过下标修改其中的元素值。修改可变数组与字典内容的标准做法是:

 
 
  1. [mutableArray replaceObjectAtIndex:1 withObject:@"dog"];  
  2. [mutableDictionary setObject:@"Galloway"forKey:@"lastName"]; 

若换用取下标操作来写,则是:

 
 
  1. mutableArray[1] = @"dog";  
  2. mutableDictionary[@"lastName"] = @"Galloway"; 

局限性

字面量语法有个小小的限制,就是除了字符串以外,所创建出来的对象必须属于Foundation框架才行。如果自定义了这些类的子类,则无法用字面量语法创建其对象。要想创建自定义子类的实例,必须采用“非字面量语法”(nonliteral syntax)。然而,由于NSArray、NSDictionary、NSNumber都是业已定型的“子族”(class cluster,参见第9条),因此很少有人会从其中自定义子类,真要那样做也比较麻烦。而且一般来说,标准的实现已经很好了,无须再改动。创建字符串时可以使用自定义的子类,然而必须要修改编译器的选项才行。除非你明白这样做的后果,否则不鼓励使用此选项,用NSString就足够了。

使用字面量语法创建出来的字符串、数组、字典对象都是不可变的(immutable)。若想要可变版本的对象,则需复制一份:

NSMutableArray *mutable = [@[@1, @2, @3, @4, @5]mutableCopy];

这么做会多调用一个方法,而且还要再创建一个对象,不过使用字面量语法所带来的好处还是多于上述缺点的。

要点

应该使用字面量语法来创建字符串、数值、数组、字典。与创建此类对象的常规方法相比,这么做更加简明扼要。

应该通过取下标操作来访问数组下标或字典中的键所对应的元素。

用字面量语法创建数组或字典时,若值中有nil,则会抛出异常。因此,务必确保值里不含nil。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值