- 博客(16)
- 收藏
- 关注

原创 SideTable结构
iOS开发者都知道,当一个对象被释放时,所有对这个对象弱引用的指针都会释放并置为nil,那么系统是如何存储这些弱引用对象的呢?又是如何在一个对象释放时,将这些指向即将释放对象的弱引用的指针置为nil的呢?下面我们通过分析SideTable的结构来进一步了解内存管理的弱引用存储细节。结构在runtime中,有四个数据结构非常重要,分别是SideTables,SideTable,weak_table_t和weak_entry_t。它们和对象的引用计数,以及weak引用相关。SideTables下面我们
2020-11-01 22:00:08
2884
2
原创 Runtime之MetaClass
对于iOS开发者来说,元类一直是一个在面试时被重点考察的点,为什么在语言设计时要增加元类这个概念?他的优点是什么?他到底有什么作用呢?这篇文章我们从Runtime源码的角度和语言设计的角度来探讨MetaClass存在的原因以及他的存在解决了哪些问题。测试题下面我们先看一下下面这个题目:- (void)classJudge { Class ccls = [NSObject class]; Class icls = [Person class]; NSLog(@"%.
2021-01-02 10:56:23
240
原创 iOS KVC 实现探究
我们都知道iOS开发中有很多黑魔法,KVC就是其中之一,在平时开发中我们也会使用KVC去获取一些系统未公开的API方法,但同时我们可能要承担一些被拒或者因系统API改变导致的问题。这篇文章我们从源码的角度分析KVC的实现。KVC使用示例- (void)kvcValueForKeyTest { self.p = [Person new]; self.p.name = @"LeeWong"; self.p.age = 30; NSLog(@"Person age = .
2020-12-27 17:55:04
252
原创 Runtime之KVO实现
KVO(Key-Value-Observer)即键值监听,我们在平时的开发中通常用来监听对象属性的变化,比如UIScrollView的ContentOffset,不过同时我们要注意在不需要继续监听的时候及时的移除监听,否则可能会导致崩溃。因此这篇文章让我们更好的了解KVO。KVO的使用下面我们来看下我们平时使用KVO的方式:@interface ViewController ()@property (nonatomic, strong) Person *man;@end@implement.
2020-12-19 20:18:22
324
1
原创 内存管理之Tagged pointer
iOS开发者对引用计数这个名词肯定不陌生,引用计数是苹果为了方便开发者管理内存而引入的一个概念,当引用计数为0时,对象就会被释放。但是,真的是所有对象都是这样吗?内存分配iOS将虚拟内存按照地址由低到高划分为如下五个区:在程序运行时,代码区,常量区以及全局静态区的大小是固定的,会变化的只有栈和堆的大小。而栈的内存是有操作系统自动释放的,我们平常说所的iOS内存引用计数,其实是就堆上的对象来说的。如何引入tagged pointer自2013年苹果推出iphone5s之后,iOS的寻址空间扩大.
2020-12-13 21:44:07
437
原创 Runtime之对象的一生
在所有的面向对象语言中,万物皆对象。Objective-C也不例外,这篇文章我们从Runtime的源码去分析一个对象从创建到销毁的整个过程中都做了哪些操作,同时也加深我们对内存管理的理解。对象的创建我们平时开发中创建一个对象的方式一般有三种alloc init NSString *str = [[NSString alloc] init];new NSString *str = [NSString new];类方法构建 NSMutableString *.
2020-12-06 19:22:12
296
原创 iOS APP启动-Main函数之前的那些事儿
在上一篇文章中我们介绍了应用启动在objc_init方法执行前的调用堆栈,根据这个堆栈我们可以看出在main函数之前实际上系统内核以及dyld还做了很多的操作,那么这篇文章我们来详细的看一下在这个过程中到底做了哪些事情。我们在来看下这这张图:从上图中我们看一看到应用启动的入口实际是_dyld_start函数,我们从XNU源码dyldStartup.s中找到了这个方法:__dyld_start__dyld_start: //..........省略掉汇编代码 // call dyldboots
2020-11-28 10:39:56
663
原创 Runtime之方法调用和方法转发
我们都知道,在iOS开发中方法的调用实现实际上是通过消息发送的机制实现的,我们可以简单的理解为:[A a];调用A类的a方法,实际上就是给类A的a方法发消息。在这个过程中又会经历:方法查找、方法调用、方法转发这几个阶段,下面我们来通过这几个阶段来看下Runtime在这几个环境是如何实现的。在研究方法调用之前,我们先看几个方法调用先关的结构,了解这些结构之后会方便我们后续了解消息的调用流程。Method在我们上文介绍方法交换时,我们利用class_getInstanceMethod方法获取某个方法
2020-11-15 14:21:06
725
原创 Runtime之方法交换
方法交换可以说是我们在开发中比较常用的方法,尤其是在一些需要埋点或者统计的位置,我们可以通过Hook系统的某些方法,通过在这些方法中添加自己代码的方式实现在不入侵业务的情况下实现功能。首先我们来看下方法交换的实现,下面这段代码使我们在网上随便找了一份方法交换的代码实现:+ (BOOL)swizzleMethod:(Class)class orgSel:(SEL)origSel swizzSel:(SEL)altSel { Method origMethod = class_getInstance
2020-11-02 23:13:28
623
原创 应用启动-Main函数之前的那些事儿
在上一篇文章中我们介绍了应用启动在objc_init方法执行前的调用堆栈,根据这个堆栈我们可以看出在main函数之前实际上系统内核以及dyld还做了很多的操作,那么这篇文章我们来详细的看一下在这个过程中到底做了哪些事情。我们在来看下这这张图:从上图中我们看一看到应用启动的入口实际是_dyld_start函数,我们从XNU源码dyldStartup.s中找到了这个方法:__dyld_start__dyld_start: //..........省略掉汇编代码 // call dyldboots
2020-11-01 22:06:07
1128
原创 Runtime之NSObject结构
简介OC是一门面向对象的语言,而对于面向对象语言来说一切皆对象。相信每个iOS开发者都很清楚在OC中NSObject是绝大多数对象的父类。OC是一门动态语言,而动态的实现则是离不开Runtime。那么OC中的对象在Runtime中又是以一种什么样的形态出现的呢?本篇文章我们来详细介绍OC对象在Runtime中的结构。NSObject我们先来看下在Runtime中NSObject的结构@interface NSObject <NSObject> {#pragma clang diagn
2020-11-01 22:03:06
303
原创 基于响应者链条的事件传递方式
随着业务越来越负责,APP中的页面也变得越来越负责,层级变的越来越深,不论项目是MVC还是MVVM架构,我们都倾向于将事件的处理放到控制器中。随着层级越来越复杂,事件处理方法越来越多,为此我们的解决方案一般都是将部分处理事件放到viewmodel中或者给控制器添加分类。但这些方法都不能避免事件一层层的传递。那么有没有更好的方法呢?随着业务越来越负责,APP中的页面也变得越来越负责,层级变的越来越深,不论项目是MVC还是MVVM架构,我们都倾向于将事件的处理放到控制器中。随着层级越来越复杂,事件处理方法越
2020-11-01 22:01:41
329
原创 Mach-O 探究
Mach-O为Mach Object文件格式的缩写,它是一种用于可执行文件,目标代码,动态库,内核转储的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性,并提升了符号表中信息的访问速度。Mach-O格式为大部分基于Mach内核的操作系统所使用的,包括NeXTSTEP, Mac OS X和iOS,它们都以Mach-O格式作为其可执行文件,动态库,目标代码的文件格式。Mach-O简介在iOS开发中,我们的代码在编译后会生成一个.app的文件(Product文件夹下),而.app文件我们
2020-11-01 21:56:30
730
原创 retain和release实现探究
前面一篇文章,我们讲到了系统为了优化数字字符串等类型的数据存储新增了一种NSTaggedPointer类型,同时我们还发现,isa指针在经过优化后,提供了19个bit位用来存储引用计数的个数。但是如果超出了这个限制呢?引用计数其实在绝大多数情况下,仅用优化的isa_t来记录对象的引用计数就足够了,但是当对象被引用次数超过 2^19 限制时,就轮到SideTable出场了。首先,我们先看下超出限制之后,系统是如何将引用计数转移的retian// 等价于直接使用对象调用retain方法inline
2020-10-31 22:28:54
687
原创 RunTime解析--Category(分类)实现
在日常的开发中,我们经常用到分类,用来给一个类添加扩展,包括对象方法、类方法、当然我们还可以通过关联对象的方式给分类添属性。但是这中间的过程是如何实现的呢?下面我们来做一个详细的解释。结构category_t我们先看下分类的结构:// 分类struct category_t { // 分类名 const char *name; // 原始类 classref_t cls; // 对象方法列表 struct method_list_t *instanc
2020-10-31 22:26:29
490
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人