3.3.4 实现方法
可以给空值对象发送任何消息,例如[nil anyMethod],这样的结果还是空值。如果使用[[object alloc] init]分配时内存不足,init消息将被发送空值,从而让整个alloc/init请求都返回空值
3.7.3 自动释放对象的生命周期
避免将属性赋值给他们自己,例如:myCar.colors=myCar.colors。属性的“释放然后保留”行为可能导致对象在能够被重新赋值和重新保留之前被释放
3.12.1 实现消息转发
在Object-C中,如果一个对象无法处理某条消息,可以将该消息转发给别的对象进行处理。要实现消息转发,必须覆盖两个方法:methodSignatureForSelector:与 forwardInvocation:
- 构建方法签名
- (NSMethodSignature *) methodSignatureForSelector : (SEL)selector { NSMethodSignature *signature = [super methodSignatureForSelector:selector]; if(nil == signature){ signature = [self.carInfo methodSignatureForSelector:selector]; } return signature; }
第二个需要覆盖的方法是forwardInvocation:。只有当一个对象确定无法处理消息时,才会调用此方法。- 转发
- (void)forwardInvocation:(NSInvocation *)invocation { SEL selector = [invocation selector]; if([self.carInfo respondsToSelector:selector]){ [invocation invokeWithTarget:self.carInfo]; } }
3.12.3 思路整理
尽管转发模拟了多继承,但NSObject绝不会混淆二者。像respondsToSelector:和isKindOfClass:这样的方法只会关心继承层次结构,不会关心转发变化。有几个可选方法允许类更好的把自己的消息遵从性表达给其他类。重新实现避respondsToSelector:和isKindOfClass:之后,其他类就可以查询开发人员自己的类。-(BOOL) respondsToSelector:(SEL)aSelector { if([super respondsToSelector:aSelector]) return YES; if([self.carInfo respondsToSelector:aSelector]) return YES; return NO; }
-(BOOL) isKindOfClass:(Class)aClass { if(aClass==[Car class]) return YES; if([Super isKindOfClass:aClass]) return YES; if([self.carInfo isKindOfClass:aClass]) return YES; return NO; }
3.12.4 超级简单的转发
在iphone上还可以使用一种更加简单的方法代替以上两个方法实现转发,但有一定的风险。-(id) forwardingTargetForSelector:(SEL)sel { if([self.carInfo respondsToSelector:aSelector]) return self.carInfo; return nil; }