- 博客(1009)
- 收藏
- 关注
原创 runtime深入解析
1.前言OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行, 而OC的动态性是由Runtime来支撑和实现的,Runtime是一套C语言的API,封装了很多动态性相关的函数,平时编写的OC代码,底层都是转换成了Runtime API进行调用。2. 基础知识2.1 Class2.2 Meta Calss2.3 Ivar2.4 Property2.5 Method2.6 Category /关联2.7 super2.三个阶段2.1.消息发送2.2.动态方法解析2
2022-03-28 21:45:09
1091
原创 Block底层详解
block详解1.前言2.block的类型2.1.总共三种类型,具体如下:2.2 __ NSGlobalBlock__2、block数据结构3、block的变量捕获(capture)2.1auto变量的捕获2.2对象类型的auto变量4、block的Copy5、__weak问题解决6、__block修饰符6.1使用6.2内存管理6.3__forwarding指针7、循环引用1.前言本文旨在对block底层进行详细的探究,源码参考libclosure-79。2.block的类型2.1.总共三种类型,
2022-03-08 22:36:04
2923
原创 简单获取class的方式
- (void)initMainBundleClasses { NSMutableArray<NSString *> *mainBundleClasses = @[].mutableCopy; unsigned int classCount = 0; const char** classNames = objc_copyClassNamesForImage([[NSBundle mainBundle] executablePath].UTF8String, &...
2021-04-15 13:18:25
221
1
原创 CATransformLayer使用
//red layer CALayer *redLayer = [CALayer layer]; redLayer.frame = (CGRect){CGPointZero, CGSizeMake(200, 200)}; redLayer.position = CGPointMake(200, 300); redLayer.backgroundColor = [UIColor redColor].CGColor; //Z轴平移 CATran...
2020-08-11 20:24:27
231
原创 遮罩实现镂空
[self.view setBackgroundColor:[UIColor redColor]]; UIView *guideView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; guideView.backgroundColor = [UIColor blackColor]; guideView.alpha = 0.6; UIBezierPat...
2020-08-07 14:23:02
283
原创 BinarySearch
public int indexOf(int[] array, int data) { if (array == null || array.length == 0) { return -1; } int begin = 0; int end = array.length; while (begin < end) { int mid = (begin + ...
2020-05-14 15:36:48
200
原创 Background Fetch
Background Fetch 是iOS7开始提供的一个数据拉取机制,主要是用于需要频繁更新内容的应用,例如社交、新闻或者天气应用。当实现了这个机制,系统会学习用户使用应用的习惯,并尽量在用户下次打开应用之前,给应用一个后台启动(或者叫后台唤醒)的机会,让应用提前可以准备数据。例如,如果用户总是在下午1点打开应用,那么系统会学习到这个习惯,并尽量在1点之前触发Background Fetc...
2020-04-29 11:49:27
2831
原创 地址变更
Significant Location Update当请求地理位置权限时,可以请求“后台定位”的权限,当有后台定位权限时,应用可以调用 CLLocationManager的startMonitoringSignificantLocationChanges方法启用“显著位置变化的监听”,当GPS位置有明显变化时(实际测试一般4、5百米),应用会在后台启动。首先,需要CLLocationMa...
2020-04-25 15:39:18
62010
原创 斐波那契数
//性能差 时间复杂度:2的n次方- (NSUInteger)fibonacci1:(NSUInteger)number { if (number <= 1) { return number; } return [self fibonacci1:number - 1] + + [self fibonacci1:number - ...
2020-04-25 00:28:00
851
原创 获取线程堆栈剩余大小
#import <pthread.h>pthread_t currentThread = pthread_self();uint8_t *endStack = pthread_get_stackaddr_np(currentThread);size_t totalStackSize = pthread_get_stacksize_np(currentThread);u...
2020-04-04 00:41:51
1700
原创 isa的地址
struct NSObject_IMPL { void *isa;};NSObject *object = [[NSObject alloc] init];struct NSObject_IMPL *obj = (__bridge struct NSObject_IMPL *)object;NSLog(@"%p, %p", &obj->isa, object...
2020-02-25 22:31:57
287
转载 fishhook源码解析
前言fishhook是fackbook开源的一个用来hook c函数的库。在iOS开发中我们一般都是对OC方法进行hook,这是因为OC的动态特性才能实现的,OC的方法调用是在运行时动态查找的。而c函数是静态,为什么同样能够hook呢?接来下就看看这其中用到了什么黑魔法!一、Mach-O文件首先,我们将iOS源代码打包后会生成一个.ipa文件,里面包含了一些资源文件以及可执行文件,这个...
2019-09-30 17:48:57
509
转载 剖析ARM64下的objc_msgSend
本文来自Mad_Mark的简书,作者 sasukeo原文原文:Dissecting objc_msgSend on ARM64原文作者:Mike Ash本文结合原文评论区Greg Parker的评论略做修改。建议结合objc_msgSend源码来阅读本文。在了解objc_msgSend的原理的同时,也可作为ARM64汇编的入门。概述每一个OC对象有一个类,每一个OC...
2019-09-30 17:39:11
1080
转载 获取任意线程调用栈的那些事
BSBacktraceLogger 是一个轻量级的框架,可以获取任意线程的调用栈,开源在我的GitHub,建议下载下来结合本文阅读。我们知道NSThread有一个类方法callstackSymbols可以获取调用栈,但是它输出的是当前线程的调用栈。在利用 Runloop 检测卡顿时,子线程检测到了主线程发生卡顿,需要通过主线程的调用栈来分析具体是哪个方法导致了阻塞,这时系统提供的方法...
2019-09-26 10:34:18
621
转载 Hook static initializers
先补充:标题中 static initializers 其实应该叫做C++ static initializers and C/C++ __attribute__(constructor) functions。使用 MachOView 打开一个MachO文件,多数情况下会看到这个section__mod_init_func。这个section的用途是什么呢?从名字大概猜测...
2019-08-13 10:46:33
778
2
转载 一种延迟 premain code 的方法
大量的premain代码,不可控,在线上随时都是炸弹。为了让开发者过渡的更“透明“,有了下面的方法。想法来源仍然是两年前的三篇分析Facebook客户端的文章:1- 探索 facebook iOS 客户端 - section fbsessiongkshttps://everettjf.github.io/2016/08/21/facebook-explore-section...
2019-08-13 10:45:15
450
转载 mmap
mmap是性能优化的必备神器,这篇文章简单罗列下相关信息。mmap是什么简单通俗不精确的说,mmap可以直接建立内存与文件的映射,进程对内存的修改可直接同步到文件内容的修改,仅有一次磁盘到内存的拷贝过程。这是Wikipedia的解释:In computing, mmap(2) is a POSIX-compliant Unix system call that maps file...
2019-08-13 10:44:05
621
转载 Hook所有+load方法(包括Category)
大概两年前刚开始做性能优化工作,为了Hook所有+load方法,是用Hopper先列出所有+load,然后使用CaptainHook在动态库中逐个指定类名来Hook每一个+load方法。写了一篇文章,先后发表到了内网(ATA)和博客,博客文章地址是: https://everettjf.github.io/2017/01/06/a-method-of-hook-objective-c-load/ ...
2019-08-13 10:42:20
2228
转载 最简单的启动任务分类
一个“有年头”的App,启动中要做的工作不断的累加,didFinishLaunchingWithOptions中的代码越来越长,AppDelegate.m文件的行数也越来越多。那么是时候分类存放了。App启动中的任务可以简单分为下面几类: 必须最早在主线程初始化的任务 可以子线程执行的任务 可以与2中的任务并行执行的主线程任务 可以在首页显示后子线程执行的任...
2019-08-13 10:40:53
216
转载 线程标识获取方法
性能优化的开发中经常需要获取线程标识,这篇文章简单罗列和对比了四种获取线程标识的方法。四种方法这四种方法如下://<NSThread:0x283903000>{number=1,name=main}[[NSThreadcurrentThread]description]//0x283903000[NSThreadcurrentThread]...
2019-08-13 10:39:07
564
转载 由「抖音二进制文件重排」想到的
2018年11月份,支付宝发布了一篇文章《支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能》,简单来说这篇文章说明、实践且验证了通过「安装包重排」可以加快Android应用的启动速度。而作为支付宝曾经的一员,很早就知道了这个方案,当时也在想iOS能否有类似的方案,很快找到了一篇“退休”的文档:Code Size Performance Guidelin...
2019-08-13 10:36:29
3454
转载 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15%
背景启动是App给用户的第一印象,对用户体验至关重要。抖音的业务迭代迅速,如果放任不管,启动速度会一点点劣化。为此抖音iOS客户端团队做了大量优化工作,除了传统的修改业务代码方式,我们还做了些开拓性的探索,发现修改代码在二进制文件的布局可以提高启动性能,方案落地后在抖音上启动速度提高了约15%。本文从原理出发,介绍了我们是如何通过静态扫描和运行时trace找到启动时候调用的函数,然后修改编...
2019-08-13 10:33:14
6155
原创 iOS获取启动开始时间
/// 获得进程的信息+ (BOOL)processInfoWithPID:(int)pid proInfo:(struct kinfo_proc*)procInfo{ int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; size_t size = sizeof(*procInfo); retu...
2019-07-30 17:19:03
1654
转载 基于 clang 插件的一种 iOS 包大小瘦身方案
引子包瘦身,包瘦身,包瘦身,重要的事情说三遍。最近公司一款 iOS APP(本文只讨论使用 Objective C 开发的 iOS 安装包) 一直在瘦身,我们团队的 APP 也愈发庞大了。而要解决这个问题,思路主要集中在两个方向,资源和代码。资源主要在于图片,方法包括移除未被引用的图片,只使用一套图片 (2x 或 3x),图片伸缩等;代码层面主要思路包括重构消除冗余,linkmap 中 s...
2019-06-27 10:53:15
574
原创 otool 分析Mach-O
otool 查看所有的Methodotool -v -s __TEXT __objc_methname mach-o的pathotool 查看被调用的Methodotool -v -s __DATA __objc_selrefs mach-o的pathotool 查看所有的Classotool -v -s __TEXT __objc_classname mac...
2019-06-18 15:24:58
1392
转载 iOS调优 | 深入理解Link Map File
Link Map File初识我们编写的源码需要经过编译、链接,最终生成一个可执行文件。在编译阶段,每个类会生成对应的.o文件(目标文件)。在链接阶段,会把.o文件和动态库链接在一起。Link Map File就是这样一个记录链接相关信息的纯文本文件,里面记录了可执行文件的路径、CPU架构、目标文件、符号等信息。为什么要理解Link Map File理解Link Map File,可以...
2019-06-18 10:57:12
688
转载 分析Mach-O文件
OSX系统自带的otool可以分析Mach-O可执行文件类似命令行工具:jtool常用命令如下:查看fat headers信息otool -f xxx.app/xxx$ otool -f xxx.app/xxxFat headersfat_magic 0xcafebabenfat_arch 2architecture 0 cputype 12 cpusubt...
2019-06-18 10:25:06
272
转载 创建CocoaPods的制作过程
使用CocoaPods来管理第三方库实在是方便,在学会了使用CocoaPods后,开始尝试创建一个自己的版本依赖库,当然,迟早要走到这一步的.创建仓库接下来实现一个首页广告循环播放功能,项目名为CLRollingCycleView本地仓库使用Xcode创建一个CLRollingCycleView项目,项目并添加Classes(核心功能)远程仓库在github上同样创建...
2019-05-08 16:20:14
242
转载 图文翔解HashTree
在各种数据结构(线性表、树等)中,记录在结构中的相对位置是随机的。因此在机构中查找记录的时需要进行一系列和关键字的比较。这一类的查找方法建立在“比较”的基础上。查找的效率依赖于查找过程中所进行的比较次数。之前我们介绍的各种基于比较的树查找算法,这些查找算法的效率都将随着数据记录数的增长而下降。仅仅是有的比较慢(时间复杂度为O(n)),有的比较快(时间复杂度是O(logn))而已。这些查找算法的...
2019-04-10 10:39:50
246
转载 mach-o文件分析
一. 先给出一个结构图,大致了解一下内部的结构:image.png主要结构分成三个部分: Header部分:保存了该文件的一些基本信息,如平台,文件类型,加载命令的个数等 loadCommends部分:根据这里的数据来确定内存的分布 Data部分:存放具体的代码和数据 data部分是以段来划分的,segment段类型如下图: 1:__PAGEZERO段:...
2019-04-07 13:33:42
772
原创 block的变量捕获
先了解一下block的本质1.block本质上也是一个OC对象,它内部也有个isa指针2.block是封装了函数调用以及函数调用环境的OC对象3.block的底层结构如下图所示为了保证block内部能够正常访问外部的变量,block有个变量捕获机制 变量类型 捕获到block内部 访问方式 局部变...
2019-03-31 13:25:35
228
原创 +load方法和+initialize方法的调用
一. load 方法1.+load方法会在runtime加载类、分类时调用2. 每个类、分类的+load,在程序运行过程中只调用一次3.调用顺序3.1先调用类的+load,按照编译先后顺序调用(先编译,先调用)3.2调用子类的+load之前会先调用父类的+load3.3.再调用分类的+load,按照编译先后顺序调用(先编译,先调用)4. 直接拿IMP 执行load方...
2019-03-30 23:50:33
303
原创 KVC
1. setValue:forKey:的原理setValue:forKey:的原理注意: 直接给成员变量赋值是不会触发KVO,但是通过KVC修改成员变量是会触发KVO2.valueForKey:的原理...
2019-03-30 17:28:06
234
转载 跳跃表原理
最近看了一种数据结构叫做skipList,redis和levelDB都是用了它。Skip List是在有序链表的基础上进行了扩展,解决了有序链表结构查找特定值困难的问题,查找特定值的时间复杂度为O(logn),他是一种可以代替平衡树的数据结构。 下面是skipList的一个介绍,转载来的,源地址:http://kenby.iteye.com/blog/1187303,为防止...
2019-03-29 10:36:29
158
转载 Dijkstra 最短路算法
上周我们介绍了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”。本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。例如求下图中的 1 号顶点到 2、3、4、5、6 号顶点的最短路径。与 Floyd-Warshall 算法一样这里仍然使用二维数组 e 来存储顶点之间边的关系,初始值如下。我们还需要用一个一...
2019-03-26 10:40:06
231
转载 Bellman-Ford 单源最短路径算法
Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法。该算法由Richard Bellman 和 Lester Ford 分别发表于 1958 年和 1956 年,而实际上 Edward F. Moore 也在 1957 年发布了相同的算法,因此,此算法也常被称为 Bellman-Ford-Moore 算法...
2019-03-26 10:15:42
1468
转载 dijkstra算法:寻找到全图各点的最短路径
dijkstra算法介绍:即迪杰斯特拉算法,是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止,是一种广度优先的搜索方法。dijkstra算法原理:最优子路径存在。假设从S→E存在一条最短路径SE,且该路径经过点A,那么可以确定SA子路径一定是S→A的最短路径。证明:反证法。如果子路径SA不是最短的,那么就必...
2019-03-22 11:42:31
1856
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人