runtime——运行时简单使用

Published 2016-09-21 10:04 592 words 3 min read

前端项目通过bridge获取客户端资源,客户端直接返回response对象Win11 光标变白消失解决方案(浏览器开启硬件加速后,在鼠标滑到文本处出现)Terminal里用option/alt + 鼠标点击,就可以让光标到指定位置Duff's Device为 UIControl 实现线程安全的 Block 事件扩展:原理与实践前端代码规范设计模式k8s前端项目利用nginx部署项目不停机Vue3+Vite+history模式+Nginx 部署二级路径iOS开发工具常用代码模板2——数据结构常用代码模板1——基础算法iOS:特殊符号大全HomeBrew 更新报错“fatal- Could not resolve HEAD to a revision”SwiftUI基本控件代码大全——1.欢迎进入软件构建的世界C++ STL简介LeetCode 70 爬楼梯(青蛙跳台阶)深入理解计算机系统(第二版) 家庭作业 第二章Swift Module 如何被全局引用LeetCode 398 随机数索引Vue 的一些指令和缩写LeetCode 486 Predict the Winner(预测赢家)浅谈iOS中的weakCocoaPods组件化——OC/Swift动静态库混用OpenGL 术语当对象接收到不能处理的消息时调用的方法命令行通过ffmpeg剪切视频iOS:如何在UITableView调用reloadData刷新结束后再同步执行后续操作统计iOS工程代码行数CMake 入门及常用变量指令手册LeetCode 6 ZigZag Conversion(Z字转换)LeetCode 106 Construct Binary Tree from Inorder and Postorder Traversal(由中序和后序遍历建立二叉树)LeetCode 5 Longest Palindromic Substring(最长回文字串)LeetCode 8 String to Integer (atoi)Objective-C Type EncodingsObjective-C:为什么分类中不能直接添加属性MeshLab数据结构与算法解析习题2.23数据结构与算法解析习题2.19数据结构与算法解析习题2.16数据结构与算法解析习题2.14数据结构与算法解析习题2.13数据结构与算法解析习题2.12数据结构与算法解析习题2.11:二分查找数据结构与算法解析习题2.10:霍纳法则(Horner's rule)数据结构与算法解析习题2.7数据结构与算法解析习题1.3数据结构与算法解析习题1.2数据结构与算法解析习题1.1centos7 mysql数据库安装和配置Fishhook-源码分析解决Mac下 Cornerstone 无法查看SVN日志的问题UIButton扩大点击范围以及关于响应者链条的思考UILabel中文带行间距的处理,限制行数,计算高度等UITableview调用reload方法时抖动问题C语言指针小结C语言数据类型和const、static关键字iOS 截取整个 scrollview 图片WxWidgets类列表objc源码分析-runtime-classiOS自动化埋点的实现iOS平台编译Ogre游戏引擎库在 Mac OS X 上安装 TensorFlowiPhone 刘海机型UI适配(X、Xs、Xs Max、Xr)关于C语言中的union虚拟机 Linux 上编 slice3r perl Build.PL 报错iOS 沙盒与 BundleCOCOAPODS技巧-创建私有仓库iOS脚本打包 ipa(.app转.ipa)Objective-C 中禁止调用指定的方法iOS 关于 UITextField 的字数限制升级 Mac OS 10.13 High Sierra 后 ruby 报错iOS 框架学习-AsyncSocketSQL语句OC优缺点以及常见bugUIViewController 的生命周期runtime——运行时简单使用iPhone6 Plus上面神秘的缝隙CocoaPods安装和使用教程(更新至Mac High Sierra)UIApplicationiOS 网络小结NSString的各种处理HTTP请求报文和HTTP响应报文,以及工作原理Vim 快捷键整理OC中nil 、NULL、 Nil 、NSNull的区别GCD 使用指南iOS常用数据类型转换关于NSNotificationCenterGit 命令MAC OS 常用技巧Description方法和NSLog函数代码重构OC单例宏Block in Objective-CObjective-C 语法 3Objective-C 语法 2Objective-C 语法 1
This post is not yet available in English. Showing the original.
运行时总结 什么是runtime? runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型、C语言函数) 实际上,平时我们编写的OC代码,底层都是基于runtime实现的 也就是说,平时我们编写的OC代码,最终都是转成了底层的runtime代码(C语言代码) runtime有什么作

运行时总结

什么是runtime?

  1. runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型、C语言函数)
  2. 实际上,平时我们编写的OC代码,底层都是基于runtime实现的

也就是说,平时我们编写的OC代码,最终都是转成了底层的runtime代码(C语言代码)

runtime有什么作用?

  1. 能动态产生一个类、一个成员变量、一个方法
  2. 能动态修改一个类、一个成员变量、一个方法
  3. 能动态删除一个类、一个成员变量、一个方法
//常见的函数、头文件
#import <objc/runtime.h> : //成员变量、类、方法
Ivar * class_copyIvarList : //获得某个类内部的所有成员变量
Method * class_copyMethodList : //获得某个类内部的所有方法
Method class_getInstanceMethod : //获得某个实例方法(对象方法,减号-开头)
Method class_getClassMethod : //获得某个类方法(加号+开头)
method_exchangeImplementations : //交换2个方法的具体实现

#import <objc/message.h> : //消息机制
objc_msgSend(.)

运行时获取成员变量

#import <objc/runtime.h>
#import <objc/message.h>

#import <objc/objc-runtime.h>

// 基于运行时,就可以不用
- (void)encodeWithCoder:(NSCoder *)encoder
{
    // Ivar : 成员变量
    unsigned int count = 0;
    // 取得所有的成员变量
    Ivar *ivars = class_copyIvarList([AKPerson class], &count);
    for (int i = 0; i<count; i++) {
        // 取得i位置的成员变量
        Ivar ivar = ivars[i];
        const char *name = ivar_getName(ivar);
        NSString *key = [NSString stringWithUTF8String:name];
    [encoder encodeObject:[self valueForKeyPath:key] forKey:key];
    }
}

id LenderClass = objc_getClass("ViewController");
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t propertie = properties[i];

        // property_getAttributes 函数将返回属性(Property)的名字,@encode 编码,以及其它特 征(Attribute)
        NSLog(@"类属性的名字%s---类属性的属性:%s",property_getName(propertie),property_getAttributes(propertie));

    }

运行时交换两个函数的实现

  
#import <objc/runtime.h>

@implementation NSObject(Extension)
+ (void)swizzleClassMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
{
    Method otherMehtod = class_getClassMethod(class, otherSelector);
    Method originMehtod = class_getClassMethod(class, originSelector);
    // 交换2个方法的实现
    method_exchangeImplementations(otherMehtod, originMehtod);
}

+ (void)swizzleInstanceMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
{
    Method otherMehtod = class_getInstanceMethod(class, otherSelector);
    Method originMehtod = class_getInstanceMethod(class, originSelector);
    // 交换2个方法的实现
    method_exchangeImplementations(otherMehtod, originMehtod);
}
@end

@implementation NSArray(Extension)
+ (void)load
{
    [self swizzleInstanceMethod:NSClassFromString(@"__NSArrayI") originSelector:@selector(objectAtIndex:) otherSelector:@selector(ak_objectAtIndex:)];
}

- (id)ak_objectAtIndex:(NSUInteger)index
{
    if (index < self.count)
    {
        return [self ak_objectAtIndex:index];
    }
    else
    {
        return nil;
    }
}

@end

@implementation NSMutableArray(Extension)
+ (void)load
{
    [self swizzleInstanceMethod:NSClassFromString(@"__NSArrayM") originSelector:@selector(addObject:) otherSelector:@selector(ak_addObject:)];
    [self swizzleInstanceMethod:NSClassFromString(@"__NSArrayM") originSelector:@selector(objectAtIndex:) otherSelector:@selector(ak_objectAtIndex:)];
}

- (void)ak_addObject:(id)object
{
    if (object != nil) {
        [self ak_addObject:object];
    }
}

- (id)ak_objectAtIndex:(NSUInteger)index
{
    if (index < self.count) {
        return [self ak_objectAtIndex:index];
    } else {
        return nil;
    }
}
@end