【转】OC的反射机制

这篇文章是抄的 嘿嘿嘿

NSObject 方法 我觉得这个大家都知道

除了个别例外,Cocoa 中大部分类都是 NSObject 的子类,因此大部分对象都继承了它所定义的方法。
NSObject 提供了一些简单的查询运行时系统信息的方法:

  • (BOOL)isKindOfClass:(Class)aClass
    Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.

  • (BOOL)isMemberOfClass:(Class)aClass
    Returns a Boolean value that indicates whether the receiver is an instance of a given class.

  • (BOOL)respondsToSelector:(SEL)aSelector
    Returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message.

  • (BOOL)conformsToProtocol:(Protocol *)aProtocol
    Returns a Boolean value that indicates whether the receiver conforms to a given protocol.

例子

if ([@”Hello World” isKindOfClass:[NSObject class]]) {
NSLog(@”YES”);
} else {
NSLog(@”NO”);
}

if ([@”Hello World” isMemberOfClass:[NSObject class]]) {
NSLog(@”YES”);
} else {
NSLog(@”NO”);
}

if ([self respondsToSelector:@selector(test)]) {
NSLog(@”YES”);
} else {
NSLog(@”NO”);
}

if ([self conformsToProtocol:@protocol(NSObject)]) {
NSLog(@”YES”);
} else {
NSLog(@”NO”);
}

消息传递介绍

在 Objective-C,直到运行时消息才会绑定到方法实现。
编译器把消息表达式(message expression)转换为调用 Objective-C 运行时函数 objc_msgSend
[receiver message] -> objc_msgSend(receiver, selector)

id objc_msgSend(id theReceiver, SEL theSelector, …)
//Sends a message with a simple return value to an instance of a class.

使用 objc_msgSend 函数,需要引入 Objective-C 运行时头文件:#import

[self test];
objc_msgSend(self, @selector(test));

通过定义在 NSObject 类中的方法 methodForSelector: ,你可以请求一个方法实现过程(procedure)的指针。

  • (IMP)methodForSelector:(SEL)aSelector
    //Locates and returns the address of the receiver’s implementation of a method so it can be called as a function.

调用 IMP,头两个需要传递的参数,第一个是消息接收的对象,第二个是 selector。

IMP test = [self methodForSelector:@selector(test)];
test(self, @selector(test));

动态方法

有些情况下,我们会想要提供动态的方法实现。

Objective-C 通过使用 @dynamic 声明属性(property)来告诉编译器,属性(property)相关的方法将会动态地提供。

你可以通过实现方法 resolveInstanceMethod: 和 resolveClassMetho: 为相应的一个实例和类方法来动态地提供一个 selector 实现。

  • (BOOL)resolveInstanceMethod:(SEL)name
    //动态调用一个实例方法

  • (BOOL)resolveClassMethod:(SEL)name
    //动态调用一个类方法.

简单的抄一抄 =- =