Effective Objective-C2.0 笔记(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28285625/article/details/89095362

多使用字面量语法(literal syntax),少用与之等价的方法

Objective-C以语法繁杂而著称。事实上的确是这样。不过从Objective-C1.0起,有一个非常简单的方式能创建NSString对象。这就是“字符串字面量”(string literal),其语法如下:

NSString *someString = @"Effective Objective-C 2.0";

如果不用这种语法的话,就要以常见的alloc及init方法来分配并初始化NSString对象了。在版本较新的编译器中,也能用这种字面量语法来声明NSNumber、NSArray、NSDictionary类的实例。使用字面量语法(literal syntax)可以缩短源代码长度,使其更为易读。

字面量数组

数组是常用的数据结构。如果不适用字面量语法,那么就要这样来创建数组:

NSArray *animals = [NSArray arrayWithObjects:@"cat",@"dog",@"mouse",@"badger", nil];

而使用字面量语法来创建则是

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

上面这种做法不仅简单,而且还利于操作数组。数组的常见操作就是取某个下标所对应的对象,这用字面量来做更为容易。如果不用字面量,那么通常会用""objectAtIndex:"方法:

NSString *dog = [animals objectAtIndex:1];

若使用字面量,则是:

 NSString *dog = animals[1];

这也叫做“取下标”操作(subscripting),与使用字面量语法的其他情况一样,这种方式也更为简洁、更易理解,而且与其他语言依下标来访问数组元素时所用的语法类似。
不过,用字面量语法创建数组时要注意,若数组元素对象中有nil,则会抛出异常,因为字面量语法实际上只是一种“语法糖(syntactic sugar)”,其效果等于是先创建一个数组,然后把方括号内的所有对象都加到这个数组中。抛出的异常会是这样:

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1]’

语法糖(syntactic sugar)也称“糖衣语法”,是指计算机语言中与另外一套语法等效但是开发中用起来却更加方便的 。语法糖可令程序更易读,减少代码出错机率。

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

id object1 = /*...*/;
id object2 = /*...*/;
id object3 = /*...*/;
NSArray *arrayA = [NSArray arrayWithObjects:object1,object2,object3, nil];
NSArray *arrayB = @[object1,object2,object3];

大家想想:如果object1与object3都指向有效的Objective-C对象,而object2是nil,那么会出现什么情况呢?按照字面量语法创建数组arrayB时会抛出异常。arrayA虽然能创建出来,但是其中却只包含有object1一个对象。原因在于,“arrayWithObjects:”方法会依次处理各个参数,直到发现nil为止,由于object2为nil,所以该方法会提前结束。
这个微妙的差别表明,使用字面量语法更为安全。抛出异常令应用程序终止执行,这比创建好数组之后发现元素少了要好。想数组中插入nil通常说明程序有错,而通过异常可以更快地发现这个错误。

字典同样也有这个问题。

可变数组与字典

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

  [mutArrary replaceObjectAtIndex:1 withObject:@"dog"];
  [mutDictionary setObject:@"Galloway" forKey:@"lastName"];

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

mutArrary[1] = @"dog";
mutDictionary[@"lastName"] = @"Galloway";

局限性

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

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

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

要点

  • 应该使用字面量语法来创建字符串,数组,数值,字典。与创建此类对象的常规方法相比,这么做更加简明扼要。
  • 应该通过取下标操作来访问数组下标或字典中键所对应的元素。
  • 用字面量语法创建数组或字典时,若值中有nil,则会抛出异常,因此,务必确保值里不含nil。

猜你喜欢

转载自blog.csdn.net/qq_28285625/article/details/89095362