Chapter 2 续
使用点语法
相比之前通过发送消息来存取实例变量,OC提供了更加方便的机制—-点语法。
语法格式:消息接受者后面加上一个”.”,在加上实例变量的名字。如果点语法用在复制号左边,就表示存方法,用在右边则代表方法。
类方法和实例方法
Objective-C中的方法分为实例方法和类方法两种。
- 类方法(class method)的作用通常是创建对象,或者获取类的某些全局属性。类方法不会作用在对象上,也不能存取实例对象。
- 实例方法(instance method)则用来操作类的对象,其中存取方法就是实例方法,用来设置和获取对象的实例变量。
###覆盖方法
子类可以覆盖(override)父类方法。
***Tip:***description方法,想某个NSObject对象发送description消息时,可以得到一个NSString对象。这个对象包含当前对象的类名和其在内存中的地址信息。
在Item.m文件中覆盖description方法。
- (NSString *)description{
NSString *dedcriptionString =
[[NSString alloc] initWithFormat:
@"%@ (%@): Worth $%d, recorded on %@",
self.itemName, self.serialNumber,
self.valueInDollars, self.dateCreated];
return dedcriptionString;
}
初始化方法
Item类目前只能使用从NSObject类继承而来的init方法初始化对象。
- (instancetype)initWithItemName:(NSString *)name
valueInDollars:(int)value
serialNumber:(NSString *)sNumber;
- (instancetype)initWithItemName:(NSString *)name;
Tips:每个初始化方法的方法名都会以英文单词init开头。
然而在一个类中,无论他有多少个初始化方法,都必须选的其中的一个作为指定初始化方法。指定初始化方法要确保对象的每一个实例变量都处在一个有效的状态。(此处的有效是指向初始化的对象发送消息时,输出结果是可预期的)
Tips:指定初始化方法的参数通常会和最重要的,最常用的实例变量相对应。
instancetype
instancetype表示方法返回类型和调用方法的对象类型相同。
***Tips:***Objective-C中,一个对象不能同时拥有两个选择器相同,但是返回类型不同的方法。
id
id的定义是“指向任意对象的指针“。
区别与instancetype只能表示方法的返回类型,id还可以用来表示变量和方法参数的类型。
实现Item类的指定初始化方法
- (instancetype)initWithItemName:(NSString *)name
valueInDollars:(int)value
serialNumber:(NSString *)sNumber{
// 调用父类的指定初始化方法
self = [super init];
// 调用父类指定的方法是否成功创建父类对象
if(self){
// 为实例变量设定初始值
_itemName = name;
_valueInDollars = value;
_serialNumber = sNumber;
// 调用系统时间赋值
_dateCreated = [[NSDate alloc] init];
}
return self;
}
self
self存在与方法中,是一个隐式(implicit)局部变量。编写方法时不需要声明self,并且程序会自动为self赋值,指向收到消息的对象自身。
super
super的工作机制:当某个对象收到消息时,系统会先从这个对象开始,查询和消息名相同的方法名。如果没有找到,则会在这个对象的父类中继续查找。该查找会沿着继承路径向上,直到找到相应的方法名为止。若找到层次结构的最顶端依旧没有找到,就会抛出一个异常。
Tips:向super发消息,其实是向self发消息,但是要求系统在查找方法时跳过当前对象,直接从父类开始查找。
初始化方法中的实例变量
在初始化方法中应该直接访问访问实例变量。
其他初始化与初始化方法链
在创建类时,需要先确定指定初始化方法,然后只在指定初始化方法中编写核心代码,其他初始化方法只需调用指定初始化方法,并传入默认值。
初始化方法的简单规则:
- 类会继承所有的初始化方法,也可以为类加入任意数量的初始化方法。
- 每个类都要选定一个指定初始化方法
- 在执行其他初始化工作之前,必须先由指定初始化方法调用父类的指定初始化方法
- 其他初始化方法要调用指定初始化方法
- 如果某个类声明的指定初始化方法与其父类不同,就必须覆盖父类的指定初始化方法并调用新的指定初始化方法。