通常我们会用alloc和init方法来分配并初始化NSString对象,“字符串字面量”(string literal)提供了一种非常简单的方式创建 NSString对象,语法如下:
NSString *str=@"String Literal Learning";
当然也可以用字面量语法来声明NSNumber、NSArray、NSDictionary类的实例。
字面量字符串和NSNumber:
例如NSNumber类,该类可以处理多种类型的数值,如果不用字面量,通常我们是这样来创建实例的:
NSNumber *num=[NSNumber numberWithInt:1];
这行代码创建了一个数字,并将其值设为整数1。那么使用字面量呢,我们来看看:
NSNumber *num=@1;
感觉到区别了吧!字面量语法更为简洁。能够以NSNumber实例表示的所有数据类型都可以使用该语法。如:
NSNumber *intNumber=@1;
NSNumber *floatNumber=@2.5f;
NSNumber *doubleNumber=@3.1415926;
NSNumber *boolNumber=@YES;
NSNumber *charNumber=@'a';
除此之外,字面量语法还可用于表达式:
int x=2;
float y=2.5f;
NSNumber *expressionNumber=@(x * y);
字面量数组:
数组是一种很常见的数据结构,通常我们是这样来创建数组的:
NSArray *fruits=[NSArray arrayWithObjects:@"apple",@"orange",@"banana",@"watermelon",nil];
字面量语法则是:
NSArray *fruits=@[@"apple",@"orange",@"banana",@"watermelon"];
这种字面量做法不仅简单,而且有利于操作数组,比如数组常见的"取下标"操作(subscripting),如果不用字面量,则通常会用“objectAtIndex:”方法:
NSString *orange=[fruits objectAtIndex:1];
若使用字面量的话,则是:
NSString *orange=fruits[1];
很明显,这种方式更为简洁、更容易理解,而且与其他语言中依下标来访问数组元素时所用的语法类似。
但是,如果数组元素对象中有nil,那么使用字面量语法创建的数组就会抛出异常。例如现在有三个对象:
id object1=/*...*/;
id object2=/*...*/;
id object3=/*...*/;
分别以两种语法创建数组:
NSArray * arrayA=[NSArray arrayWithObjects:object1,object2,object3,nil];
NSArray *arrayB=@[object1,object2,object3];
现在假设object1和object3都是有效的OC对象,而object2是nil,那么按字面量语法创建的数组arrayB时就会抛出异常,而arrayA虽然能创建成功,但却只含有object1一个对象,因为“arrayWithObjects:”方法会依次处理各个参数,直到发现nil为止,由于object2是nil,所以该方法会提前结束。这个微妙的差别表明,使用字面量语法更为安全,抛出异常令程序终止,总比创建还数组之后才发现元素个数少了更好。向数组中插入nil通常是说明程序有错,通过异常可以使我们更快地发现这个错误。
字面量字典:
“字典”(Dictionary)是一种映射型数据结构,可向其中添加键值对。OC中字典的创建方式如下:
NSDictionary *personData=[NSDictionary dictionaryWithObjectsAndKeys:@"Matt",@"firstName",@"Galloway",@"lastName",[NSNumber numberWithInt:28],@"age",nil];
这样的<对象>,<键>,<对象>,<键>写法是不是很困惑?!来看看字面量的写法吧:
NSDictionary *persinData=@{@"firstName":@"Matt",@"lastName":@"Galloway",@"age":@28};
好理解多了吧!字典中的键和对象都必须是OC对像,所以整数28需要封装在NSNumber实例中。和数组一样,用字面量语法创建字典时,一旦有值为nil,就会抛出异常,同理,这也有助于我们查错。
字典也可以像数组那样用字面量语法访问。按照特定键访问其值的传统做法是:
NSString *lastName=[personData objectForKey:@"lastName"];
与之等效的字面量语法则是:
NSString *lastName=personData[@"lastName"];
可以看到,这样写省去了冗赘的语法,使代码简单易懂。
可变数组与字典:
如果数组和字典对象是可变的(mutable),那么也可以通过下标修改其中的元素值。修改可变数组和字典内容的标准做法是:
[mutableArray replaceObjectAtIndex:1 withObject:@"orange"];
[mutableDictionary setObject:@"Galloway" forKey:@"lastName"];
若换用取下标操作来写,则是:
mutableArray[1]=@"orange";
mutableDictionary[@"lastName"]=@''Galloway";
说了这么多字面量语法的好处,但是人无完人嘛,字面量语法又个小小的限制,即除了字符串以外,所创建出来的对象必须属于Foundation框架才行。如果自定义了这些类的子类,则无法用字面量语法创建其对象。另外,使用字面量语法创建出来的字符串、数组、字典对象都是不可变的(immutable)。如果想可变版本的对象,则需要复制一份:
NSMutableArray *mutable=[@[@1,@2,@3,@4,@5]mutableCopy];
这么做会多调用一个方法,而且还要再创建一个对象,不过使用字面量语法所带来的好处还是多于其缺点的。
详情可参考书籍:Effective Objective-C 2.0