标签:
11关于objc_msgSend的作用
其原型为:void objc_msgSend(id self, SEL cmd,...)
objc_msgSend_stret 如果待发送的消息要返回结构体,交由此函数处理;
objc_msgSend_fpret 如果消息返回的是浮点数,交由此函数处理;
objc_msgSendSuper 如果要给超类发消息,交由此函数处理。
消息由接受者、选择子及参数构成。给某对象“发送消息(invoke a message)”也就相当于在该对象上“调用方法(call a method)”。
给某对象的全部消息都要由“动态消息派发系统(dynamic message dispatch system)”来处理,该系统会查出对应的方法,并执行其代码。
12消息转发机制
对象在收到无法解读的消息后,首先将调用类方法+(BOOL)resolveInstanceMethod:(SEL)selector
备援接受者,接受者有第二次机会处理未知的选择子,调用-(id)forwardingTargetForSelector:(SEL)selector
最后启用完整的消息转发机制,创建NSInvocation对象,将未处理的消息的全部细节封装其中,调用-(void)forwardInvocation:(NSInvocation *)invocation
若对象无法响应某个选择子,则进入消息转发流程。
若通过运行期的动态方法解析功能,我们可以在需要用到某个方法时再将其加入某类中。
对象可以把其无法解读的某些选择子转交给其他对象处理。
经过上述两步后,如果还是没有办法处理选择子,那就启动完整的消息转发机制。
13用“方法调配技术”调试“黑盒方法”
在运行期,可以向类中新增或者替换选择子对象的方法实现,调用void method_exchangeImplementations(Method m1,Method m2)
调用method class_getInstanceMethod(Class aClass, SEL aSelector) 获取方法
使用另一份实现来替换原有的方法实现,这叫做“方法调配”,开发者常用此技术向原有实现中添加新功能。
一般来说,只有调试程序时才需要在运行期修改方法实现,这种做法不宜滥用。
14理解“类对象”的用意
描述Objective-C对象所用的数据结构定义在运行期程序库的头文件里,id类型本身也定义在这里
typedef struct objc_object{
Class isa;
}*id;
每个对象结构体的首个成员是Class类的变量,该变量定义了对象所属的类,称为“isa”指针。Class对象也定义在运行期程序库的头文件中:
typedef struct objc_class *Class;
struct objc_class{
Class isa;
Class super_class;
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_mehtod_list *methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
};
每个实例都有一个指向Class 对象的指针,用以表明其类型,而这些Class对象则构成了类的继承体系。
如果对象类型无法在编译期确定,那么就应该使用类型信息查询方法来探知,“isMemberOfClass”、“isKindOfClass”。
尽量使用类型信息查询方法来确定对象类型,而不要直接比较类对象,因为某些类对象可能实现了消息转发功能。
15用前缀避免命名空间冲突
选择与你的公司、应用程序或者二者皆有关联的名称作为类名的前缀,并在所有代码中均使用这一前缀。
若自己所开发的程序库中用到了第三方库,则应为其中的名称加上前缀。
标签:
原文地址:http://www.cnblogs.com/cobb/p/5002687.html