Runtime的介绍与简单运用(一)

runtime简称运行时

        我们都知道Object-C是一种是根据C语言所衍生出来的语言,因此我们的代码在程序运行过程中都会被转化成C代码执行,而runtime就相当于这个桥梁,对于一个想要真正理解OC语言的人,学习runtime是必不可少的,好比想要深刻理解java,映射是必不可少一样。

例如[objc logMyInfo];会被转化成objc_msgSend(objc, @selector(logMyInfo));。

OC中一切都被设计成了对象,我们都知道一个类被初始化成一个实例,这个实例是一个对象。实际上一个类本质上也是一个对象,在runtime中用结构体表示。

例如导入#import <objc/runtime.h>我们可以从runtime中看到

/// An opaque type that represents a method in a class definition.描述类中的一个方法
typedef struct objc_method *Method;

/// An opaque type that represents an instance variable.实例变量
typedef struct objc_ivar *Ivar;

/// An opaque type that represents a category. 类别Category
typedef struct objc_category *Category;

/// An opaque type that represents an Objective-C declared property.类中声明的属性
typedef struct objc_property *objc_property_t;
//类在runtime中的表示
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
    //指针,顾名思义,表示是一个什么,
    //实例的isa指向类对象,类对象的isa指向元类
#if !__OBJC2__
    //父类
    Class super_class                                        OBJC2_UNAVAILABLE;
    //类名
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    //成员变量列表
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    //方法列表
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    //缓存  一种优化,调用过的方法存入缓存列表,下次调用先找缓存
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    //协议列表
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif
    
} OBJC2_UNAVAILABLE;


实战应用,获取类属性列表

1、首先我们先新建一个工程,然后创建一个测试类文件TestClass.h

2、然后新建一些测试类属性,代码如下

h文件

#import <Foundation/Foundation.h>

@protocol TestDelegate <NSObject>

- (void)testDelegateMethod;

@end

@interface TestClass : NSObject

@property (nonatomic,weak) id<TestDelegate> delegate;
@property (nonatomic,strong) NSString *outPrOne;

- (void)thisTestMethod;

@end

/**
 测试代理
 */
@protocol TestDelegateTwo <NSObject>

- (void)testDelegateMethodTwo;

@end
@interface TestClassTwo : NSObject
@property (nonatomic,weak) id<TestDelegateTwo> delegateTwo;

- (void)thisTestMethodTwo;

@end
m文件
#import "TestClass.h"

@interface TestClass ()<TestDelegateTwo>

@end

@implementation TestClass
{
    NSString *instanceOne;
    TestClassTwo *testTwo;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        testTwo.delegateTwo = self;
    }
    return self;
}
- (void)thisTestMethod{
    if ([self.delegate respondsToSelector:@selector(testDelegateMethod)]) {
        [self.delegate testDelegateMethod];
    }
    [testTwo thisTestMethodTwo];
}

- (void)testDelegateMethodTwo{
    NSLog(@"thisTestMethodTwo");
}

@end

@implementation TestClassTwo

- (void)thisTestMethodTwo{
    if ([self.delegateTwo respondsToSelector:@selector(testDelegateMethodTwo)]) {
        [self.delegateTwo testDelegateMethodTwo];
    }
}

@end
3、然后在viewController新建此类,进行测试,代码如下

#import "ViewController.h"
#import "TestClass.h"
#import <objc/runtime.h>
@interface ViewController ()<TestDelegate>

@property (nonatomic,strong) TestClass *testClass;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _testClass = [TestClass new];
    _testClass.delegate = self;
    unsigned int count;
    //获取属性列表
    objc_property_t *propertyList = class_copyPropertyList([_testClass class], &count);
    for (int i=0; i<count; i++) {
        const char *propertyName = property_getName(propertyList[i]);
        NSLog(@"property---->%@", [NSString stringWithUTF8String:propertyName]);
    }
    
    //获取方法列表
    Method *methodList = class_copyMethodList([_testClass class], &count);
    for (int i=0; i<count; i++) {
        Method method = methodList[i];
        NSLog(@"method---->%@", NSStringFromSelector(method_getName(method)));
    }
    
    //获取成员变量列表
    Ivar *ivarList = class_copyIvarList([_testClass class], &count);
    for (int i=0; i<count; i++) {
        Ivar myIvar = ivarList[i];
        const char *ivarName = ivar_getName(myIvar);
        NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]);
    }
    [_testClass thisTestMethod];
    //获取协议列表
    __unsafe_unretained Protocol **protocolList = class_copyProtocolList([_testClass class], &count);
    for (int i=0; i<count; i++) {
        Protocol *myProtocal = protocolList[i];
        const char *protocolName = protocol_getName(myProtocal);
        NSLog(@"protocol---->%@", [NSString stringWithUTF8String:protocolName]);
    }
}

- (void)testDelegateMethod{
    NSLog(@"12111");
}
控制台输出如下

2017-02-06 18:34:39.920 RuntimeDemo[10997:466991] property---->innerPrOne
2017-02-06 18:34:39.921 RuntimeDemo[10997:466991] property---->delegate
2017-02-06 18:34:39.921 RuntimeDemo[10997:466991] property---->outPrOne
2017-02-06 18:34:39.922 RuntimeDemo[10997:466991] property---->hash
2017-02-06 18:34:39.922 RuntimeDemo[10997:466991] property---->superclass
2017-02-06 18:34:39.923 RuntimeDemo[10997:466991] property---->description
2017-02-06 18:34:39.923 RuntimeDemo[10997:466991] property---->debugDescription
2017-02-06 18:34:39.924 RuntimeDemo[10997:466991] method---->testDelegateMethodTwo
2017-02-06 18:34:39.925 RuntimeDemo[10997:466991] method---->thisTestMethod
2017-02-06 18:34:39.926 RuntimeDemo[10997:466991] method---->outPrOne
2017-02-06 18:34:39.926 RuntimeDemo[10997:466991] method---->setOutPrOne:
2017-02-06 18:34:39.927 RuntimeDemo[10997:466991] method---->innerPrOne
2017-02-06 18:34:39.927 RuntimeDemo[10997:466991] method---->setInnerPrOne:
2017-02-06 18:34:39.928 RuntimeDemo[10997:466991] method---->.cxx_destruct
2017-02-06 18:34:39.928 RuntimeDemo[10997:466991] method---->setDelegate:
2017-02-06 18:34:39.929 RuntimeDemo[10997:466991] method---->delegate
2017-02-06 18:34:39.929 RuntimeDemo[10997:466991] method---->init
2017-02-06 18:34:39.930 RuntimeDemo[10997:466991] Ivar---->instanceOne
2017-02-06 18:34:39.931 RuntimeDemo[10997:466991] Ivar---->testTwo
2017-02-06 18:34:39.931 RuntimeDemo[10997:466991] Ivar---->_delegate
2017-02-06 18:34:39.932 RuntimeDemo[10997:466991] Ivar---->_outPrOne
2017-02-06 18:34:39.932 RuntimeDemo[10997:466991] Ivar---->_innerPrOne
2017-02-06 18:34:39.933 RuntimeDemo[10997:466991] 12111
2017-02-06 18:34:39.933 RuntimeDemo[10997:466991] protocol---->TestDelegateTwo

由此可知此类所有属性与方法,以及该类所遵守的协议

在下一篇文章我们将介绍如何运用Runtime进行方法拦截


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值