2.在类的头文件中尽量少引入其他头文件
给出一个类EOCPerson;
//EOCPerson.h
#import <Foundation/Foundation.h>
@interface EOCPerson : NSObject
@property (nonatomic, strong) NSString* firstName;
@property (nonatomic, strong) NSString* lastName;
@end
//EOCPerson.m
#import "EOCPerson.h"
@implementation EOCPerson
//Implementation of methods
@end
用OC语言编写任何类几乎都需要引入Foundation.h。如果不在该类本身引入这个文件的话,那么就要引入与其超累所属框架的“基本头文件”。例如,在创建iOS应用时,通常会继承UIViewController类。而这些字类的头文件需要引入UIKit.h
现在如果,你创建了一个EOCEmployer的新类,然后觉得可能每个EOCPerson实例都应该有一个EOCEmployer。于是,直接为其添加一项属性:
//EOCPerson.h
#import <Foundation/Foundation.h>
@interface EOCPerson : NSObject
@property (nonatomic, strong) NSString* firstName;
@property (nonatomic, strong) NSString* lastName;
@property (nonatomic, strong) EOCEmployer* employer;
@end
然鹅这么做有一个问题:在编译引入EOCPerson.h的文件时,EOCEmployer并不可见,所以通常的解决办法时加入下面一行:
#import "EOCEmployer.h"
这种办法可行,但是不够优雅。在编译一个使用了EOCPerson类的文件时,不需要知道EOCEmployer的全部细节。所以可以使用下面的方法:
@class EOCEmployer;
这种做法叫做“前向声明”EOCEmployer类
然后在EOCPerson.m文件中加入:
#import "EOCEmployer"
也就是在其实现文件中来引入EOCEmployer这个类,将引入头文件的实际尽量延后,只有在确立需要时才引入,这样可以减少类的使用者所引用的头文件数量,缩短编译时间。
向前声明也解决了两个类相互引用的问题,如果要为EOCEmployer加入新增及删除雇员的方法,那么头文件中会加入下述定义:
- (void) addEmployee:(EOCPerson*) person;
- (void) deleteEmployee:(EOCPerson*) person;
此时,若要编译EOCEmployer,则编译器必须知道EOCPerson这个类,而要编译EOCPerson,又必须知道EOCEmployer这个类,最终会导致“循环引用”。
当然使用#import而非#include,指令不会导致死循环,但是这两个类里面会有一个无法被正确编译。
3.多使用字面量语法、少用与之等价的方法
OC以语法繁杂而著称,从OC 1.0起,有一种简单的方式能创建NSString对象,名叫做“字符串字面量”:
NSString* something = @"Effective Objective-C 2.0";
如果不想使用这种语法的话,那只能用alloc – init的操作来分配和初始化NSString对象了。所以尽可能用字面量语法来使自己的代码更具有可读性。
字面数值
NSNumber* someNumber = [NSNumber numberWithInt:1];
改为字面量写法:
NSNumber* someNumber = @1;
当然,所有可以被以NSNumber实例表示的数据类型都可以使用该语法:
NSNumber* intNumber = @1;
NSNumber* floatNumber = @2.5f;
NSNumber* doubleNumber = @3.14159;
NSNumber* boolNumber = @YES;
NSNumber* charNumber = @'a';
字面量数组
NSArray* anArray = [NSArray arrayWithObjects:@"C", "C++", @"OC", nil];
改为字面量写法:
NSArray* anArray = @[@"C", @"C++", @"OC"];
除了创建数组,对于操作数组元素,也是很简单的:
NSString* langC = [anArray objectAtIndex:1];
改为字面量写法:
NSString* langC = anArray[1];
字面量字典
NSDictionary* personData = [NSDictionary dictionaryWithObjectsAndKeys:@"Mastt", @"firstName", @"Galloway", @"lasyNmae", [NSNumber numberWithInt:28], @"age", nil];
改为字面量写法:
NSDictionary* personData = @{@"firstName": @"Matt", @"lastName": @"Galloway", @"age": @"28"};
可变数组与字典
若要修改其中的元素
[mutableArray replaceObjectAtIndex:1 withObject:@"dog"];
[mutableDictionary setObject:@"Galloway"forKey:@"lastName"];
改为字面量写法:
mutableArray[1] = @"dog";
muatbleDictionary[@"lastName" = @"Galloway";
局限性
字面量语法有个小小的限制:就是除了字符串以外,所创建出来的对象必须是属于Foundation框架才行。
使用字面量语法创建出来的字符串、数组、字典对象都是不可变的类型,如果需要使用可变版本的对象,请复制一份。