《Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法》 笔记2 多用字面量语法,少用与之等价的方法

多用字面量语法,少用与之等价的方法


字面数值

有时需要把整数、浮点数、布尔值封入Objective-C对象中。这种情况下可以用NSNumber类,该类可处理多种类型的数值。若是不用字面量,那么就需要按下述方式创建实例:
 

 
 
  1. NSNumber *someNumber = [NSNumber numberWithInt:1]; 

上面这行代码创建了一个数字,将其值设为整数1。然而使用字面量能令代码更为整洁:
 

 
 
  1. NSNumber *someNumber = @1; 

大家可以看到,字面量语法更为精简。不过它还有很多好处。能够以NSNumber实例表示的所有数据类型都可使用该语法。例如:
 

 
 
  1. NSNumber *intNumber = @1;  
  2. NSNumber *floatNumber = @2.5f;  
  3. NSNumber *doubleNumber = @3.14159;  
  4. NSNumber *boolNumber = @YES;  
  5. NSNumber *charNumber = @'a'; 

字面量语法也适用于下述表达式:
 

 
 
  1. int x = 5;  
  2. float y = 6.32f;  
  3. NSNumber *expressionNumber = @(x * y); 

以字面量来表示数值十分有用。这样做可以令NSNumber对象变得整洁,因为声明中只包含数值,而没有多余的语法成分。


字面量数组

 
 
  1. NSArray *animals = @[@"cat", @"dog", @"mouse", @"badger"]; 
  1. NSString *dog = animals[1]; 

不过,用字面量语法创建数组时要注意,若数组元素对象中有nil,则会抛出异常,因为字面量语法实际上只是一种“语法糖”(syntactic sugar),其效果等于是先创建了一个数组,然后把方括号内的所有对象都加到这个数组中。抛出的异常会是这样:
 

 
 
  1. *** Terminating app due to uncaught exception  
  2. 'NSInvalidArgumentException', reason: '***  
  3. -[__NSPlaceholderArray initWithObjects:count:]: attempt to  
  4. insert nil object from objects[0]' 

  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通常说明程序有错,而通过异常可以更快地发现这个错误。


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

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

 
 
  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];

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









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值