Runtime入门(一)

本文介绍了Objective-C运行时(runtime)的基本概念与核心功能,包括如何使用runtime获取类的属性、成员变量、方法及协议列表等关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

早就听说runtime很神奇,但是一直都不太明白,也不怎么会用。只有在catagory里添加属性的时候才会用到一下。
高大上的东西不会用,总是让人难过。网上的文章很多,但是要不说的太复杂,要不说的太简单,太碎片化了。但是还是要感谢网上的大神们,这里总结一下,做个整理,记录。

runtime简称运行时,就是在程序运行时的一些机制,最主要的就是发送消息机制。当OC在编译的时候,一个函数只要申明了,那么编译就不会出错。但是当程序运行的时候,如果使用了这个函数,那么就会报错。所以是在程序运行的时候才决定具体调用哪一个函数。
程序中的OC代码,在程序运行的过程中都会被转化成runtime的C语言代码执行。

1.了解一下
在Xcode中打开文档 ->Help ->Documentation and API Reference ,快捷键(shift + command +0) ,输入runtime,我们可以看到runtime中函数的介绍。
这里写图片描述

有了文档,就可以边查看文档边学了。虽然文档是万恶的英文。。。(个人觉得除非是英文666,要不看英文文档都没有耐性, 但是开发中一些棘手的BUG还是得去stackoverflow上看英文,曾经因为一个BUG在stackoverflow上看了一下午英文,眼睛都差点看瞎了。)

在使用runtime的文件中要加入头文件

#import <objc/runtime.h>

然后点进去看看

/// 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.
/// 类别
typedef struct objc_category *Category;

/// An opaque type that represents an Objective-C declared property.
/// 公开的属性
typedef struct objc_property *objc_property_t;
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#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;

这是一个结构体,不过现在好像被弃用了,并且还列出了替代方法
All other structures deprecated in favor of opaque types and functional API. Substitutes are shown in the following tables.
这里写图片描述

2.基本用法
照着API文档,我们来写几个方法.
1.获取某个类的属性

//添加三个属性,2个变量
@interface ViewController ()
{
    NSString *_testOne;
    NSArray *_testNsarr;
}

@property (nonatomic, strong) NSString *testTwo;
@property (nonatomic, strong) NSNumber *testNum;
@property (nonatomic, strong) Config   *config;
@end

- (void)getPropertyList{

    unsigned int count = 0;
    objc_property_t *propertyList = class_copyPropertyList([ViewController class], &count);
    for (int i = 0; i < count; i++) {
        const char *propertyName = property_getName(propertyList[i]);

        NSLog(@"property = %@",[NSString stringWithUTF8String:propertyName]);
    }

    free(propertyList);
//    必须释放,不然又内存警报

}

可以看到结果,把三个属性都打印出来了
这里写图片描述

2.获取某个类的成员变量

- (void)getIvarList{
    unsigned int count;

    Ivar * ivarList = class_copyIvarList([self class], &count);
    for (int i = 0; i < count; i++) {
        const char *ivarName = ivar_getName(ivarList[i]);
        NSLog(@"ivarName = %@",[NSString stringWithUTF8String:ivarName]);
    }
    free(ivarList);
    NSLog(@"-----------------------------\n\n\n");
}

3.获取某个类的方法

- (void)getMethodList{
    unsigned int count = 0;

    Method *methodList = class_copyMethodList([ViewController class], &count);
    for (int i = 0; i < count; i++) {
        SEL methodName = method_getName(methodList[i]);
        const char *selName = sel_getName(methodName);
//        NSLog(@"method = %@",NSStringFromSelector(methodName));
         NSLog(@"method = %@",[NSString stringWithUTF8String:selName]);
    }
    free(methodList);

结果不止包含我们所写的方法,还有属性的set,get方法。另外看到一个奇怪的方法 ”.cxx_destruct“。.cxx_destruct方法原本是为了C++对象析构的,ARC借用了这个方法插入代码实现了自动内存释放的工作。

4.获取某个类的协议列表 (某个类遵守的协议,)

- (void)getProtocolList{
    unsigned int count ;
//    __unsafe_unretained :
    __unsafe_unretained Protocol ** protocolList = class_copyProtocolList([UITableViewController class], &count);
    for (int i = 0; i < count; i++) {
        const char *protocolName = protocol_getName(protocolList[i]);
        NSLog(@"protocolName = %@",[NSString stringWithUTF8String:protocolName]);
    }
    free(protocolList);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值