博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【深入学习iOS开发(一)】Objective-C Reflection(Objective-C 反射机制)
阅读量:6372 次
发布时间:2019-06-23

本文共 3630 字,大约阅读时间需要 12 分钟。

Objective-C Reflection(Objective-C 反射机制)

 

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 <objc/message.h>

[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
    Dynamically provides an implementation for a given selector for an instance method.
  • + (BOOL)resolveClassMethod:(SEL)name
    Dynamically provides an implementation for a given selector for a class method.

 

定义一个 User 类

在 .h 文件,定义属性 name

以往,会在相应的 .m 文件,使用 @synthesize 声明属性 name,这样编译器会自动生成相应的 setter 和 getter 方法

但是,当使用 @dynamic 声明属性 name 时,就必须自己提供相应的 setter 和 getter 方法

Override + (BOOL)resolveInstanceMethod:(SEL)name 方法

当类实例调用 - (void)setName:(NSString) aName 或  -(NSString *)name 方法时,就为其动态地提供方法实现

#import 
@interface User : NSObject { NSString *name;}@property (nonatomic, retain) NSString *name;@end

 

#import "User.h"#import 
@implementation User@dynamic name;- (void)dynamicSetName:(NSString *) aName { if (name != nil) { [name release]; name = nil; } [aName retain]; name = aName;}- (NSString *)dynamicName { return name;}+ (BOOL)resolveInstanceMethod:(SEL)sel { NSLog(@"Instance Method: %@", NSStringFromSelector(sel)); if ([@"setName:" isEqualToString:NSStringFromSelector(sel)]) { class_addMethod([self class], sel, [self instanceMethodForSelector:@selector(dynamicSetName:)], "v@:"); return YES; } else if ([@"name" isEqualToString:NSStringFromSelector(sel)]) { class_addMethod([self class], sel, [self instanceMethodForSelector:@selector(dynamicName)], "@"); return YES; } return [super resolveInstanceMethod:sel];}@end

 

参考:

 

转载于:https://www.cnblogs.com/dyingbleed/archive/2013/05/05/3029547.html

你可能感兴趣的文章
256MB内存也装Vista
查看>>
MAC OX 安装rtx客户端和svn客户端
查看>>
Oracle GoldenGate 11g单向DDL配置实战
查看>>
《Essential Linux Device Drivers》第1章
查看>>
[CTO札记]:多做[乘法],少些[加法]
查看>>
移动的MobileMarket个人终于可以上传软件了
查看>>
Java中使用Runtime和Process类运行外部程序
查看>>
数据库泵(expdp/impdp)导入导出流程
查看>>
STM8S 串口应用 UART2 STM8S105
查看>>
ant 构建时遇到 “非法字符: \65279”的解决办法
查看>>
AES算法介绍
查看>>
数据库实例: STOREBOOK > 用户 > 编辑 用户: PUBLIC
查看>>
莫比乌斯反演学习【莫比乌斯反演】
查看>>
c#socket编程基础
查看>>
WORKAREA_SIZE_POLICY参数引起的ORA-04030错误
查看>>
C#正则表达式通过HTML提取网页中的图片src
查看>>
myloader恢复mysql数据库示例
查看>>
[20170204]dg环境修改sys口令.txt
查看>>
宏定义
查看>>
[20171117]参数filesystemio_options.txt
查看>>