自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

原创 BinarySearch

public int indexOf(int[] array, int data) { if (array == null || array.length == 0) { return -1; } int begin = 0; int end = array....

2020-05-14 15:36:48 35 0

原创 Background Fetch

Background Fetch 是iOS7开始提供的一个数据拉取机制,主要是用于需要频繁更新内容的应用,例如社交、新闻或者天气应用。当实现了这个机制,系统会学习用户使用应用的习惯,并尽量在用户下次打开应用之前,给应用一个后台启动(或者叫后台唤醒)的机会,让应用提前可以准备数据。例如,如果用户总是...

2020-04-29 11:49:27 41 0

原创 地址变更

Significant Location Update 当请求地理位置权限时,可以请求“后台定位”的权限,当有后台定位权限时,应用可以调用 CLLocationManager的startMonitoringSignificantLocationChanges方法启用“显著位置变化的监听”,当GP...

2020-04-25 15:39:18 49 0

原创 斐波那契数

//性能差 时间复杂度:2的n次方 - (NSUInteger)fibonacci1:(NSUInteger)number { if (number <= 1) { return number; } return [self fibonacci1:numb...

2020-04-25 00:28:00 164 0

原创 获取线程堆栈剩余大小

#import <pthread.h> pthread_t currentThread = pthread_self(); uint8_t *endStack = pthread_get_stackaddr_np(currentThread); size_t totalStack...

2020-04-04 00:41:51 61 0

原创 load和initialize方法的区别

一、调用方式 1、load 是根据IMP直接调用 2、initialize是通过objc_msgSend调用 二、调用时刻 1、load是runtime加载类、分类的时候调用(只调用一次) 2、initialize类第一次接收消息的时候调用,每个类只会调用一次(父类可能被调用多次) 三...

2020-03-15 22:49:14 33 0

原创 isa superclass的总结

如下图

2020-03-03 19:52:59 17 0

原创 isa的地址

struct NSObject_IMPL { void *isa; }; NSObject *object = [[NSObject alloc] init]; struct NSObject_IMPL *obj = (__bridge struct NSObject_IMPL *)o...

2020-02-25 22:31:57 41 0

转载 fishhook源码解析

前言 fishhook是fackbook开源的一个用来hook c函数的库。在iOS开发中我们一般都是对OC方法进行hook,这是因为OC的动态特性才能实现的,OC的方法调用是在运行时动态查找的。而c函数是静态,为什么同样能够hook呢?接来下就看看这其中用到了什么黑魔法! 一、Mach-O文...

2019-09-30 17:48:57 87 0

转载 剖析ARM64下的objc_msgSend

本文来自Mad_Mark的简书,作者 sasukeo 原文 原文:Dissecting objc_msgSend on ARM64 原文作者:Mike Ash 本文结合原文评论区Greg Parker的评论略做修改。 建议结合objc_msgSend源码来阅读本文。在了解objc_msg...

2019-09-30 17:39:11 80 0

转载 获取任意线程调用栈的那些事

BSBacktraceLogger 是一个轻量级的框架,可以获取任意线程的调用栈,开源在我的GitHub,建议下载下来结合本文阅读。 我们知道NSThread有一个类方法callstackSymbols可以获取调用栈,但是它输出的是当前线程的调用栈。在利用 Runloop 检测卡顿时,子线程检测...

2019-09-26 10:34:18 65 0

转载 Hook static initializers

先补充:标题中 static initializers 其实应该叫做C++ static initializers and C/C++ __attribute__(constructor) functions。 使用 MachOView 打开一个MachO文件,多数情况下会看到这个section...

2019-08-13 10:46:33 116 1

转载 一种延迟 premain code 的方法

大量的premain代码,不可控,在线上随时都是炸弹。为了让开发者过渡的更“透明“,有了下面的方法。 想法来源仍然是两年前的三篇分析Facebook客户端的文章: 1- 探索 facebook iOS 客户端 - section fbsessiongks https://everet...

2019-08-13 10:45:15 97 0

转载 mmap

mmap是性能优化的必备神器,这篇文章简单罗列下相关信息。 mmap是什么 简单通俗不精确的说,mmap可以直接建立内存与文件的映射,进程对内存的修改可直接同步到文件内容的修改,仅有一次磁盘到内存的拷贝过程。 这是Wikipedia的解释: In computing, mmap(2) i...

2019-08-13 10:44:05 376 0

转载 Hook所有+load方法(包括Category)

大概两年前刚开始做性能优化工作,为了Hook所有+load方法,是用Hopper先列出所有+load,然后使用CaptainHook在动态库中逐个指定类名来Hook每一个+load方法。写了一篇文章,先后发表到了内网(ATA)和博客,博客文章地址是: https://everettjf.githu...

2019-08-13 10:42:20 336 0

转载 最简单的启动任务分类

一个“有年头”的App,启动中要做的工作不断的累加,didFinishLaunchingWithOptions中的代码越来越长,AppDelegate.m文件的行数也越来越多。那么是时候分类存放了。 App启动中的任务可以简单分为下面几类: 必须最早在主线程初始化的任务 可以子线...

2019-08-13 10:40:53 66 0

转载 线程标识获取方法

性能优化的开发中经常需要获取线程标识,这篇文章简单罗列和对比了四种获取线程标识的方法。 四种方法 这四种方法如下: //<NSThread:0x283903000>{number=1,name=main} [[NSThreadcurrentThread]description]...

2019-08-13 10:39:07 36 0

转载 由「抖音二进制文件重排」想到的

2018年11月份,支付宝发布了一篇文章《支付宝 App 构建优化解析:通过安装包重排布优化 Android 端启动性能》,简单来说这篇文章说明、实践且验证了通过「安装包重排」可以加快Android应用的启动速度。 而作为支付宝曾经的一员,很早就知道了这个方案,当时也在想iOS能否有类似的方...

2019-08-13 10:36:29 1090 0

转载 抖音研发实践:基于二进制文件重排的解决方案 APP启动速度提升超15%

背景 启动是App给用户的第一印象,对用户体验至关重要。抖音的业务迭代迅速,如果放任不管,启动速度会一点点劣化。为此抖音iOS客户端团队做了大量优化工作,除了传统的修改业务代码方式,我们还做了些开拓性的探索,发现修改代码在二进制文件的布局可以提高启动性能,方案落地后在抖音上启动速度提高了约15%...

2019-08-13 10:33:14 2385 0

原创 iOS获取启动开始时间

/// 获得进程的信息 + (BOOL)processInfoWithPID:(int)pid proInfo:(struct kinfo_proc*)procInfo { int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; ...

2019-07-30 17:19:03 402 0

转载 基于 clang 插件的一种 iOS 包大小瘦身方案

引子 包瘦身,包瘦身,包瘦身,重要的事情说三遍。 最近公司一款 iOS APP(本文只讨论使用 Objective C 开发的 iOS 安装包) 一直在瘦身,我们团队的 APP 也愈发庞大了。而要解决这个问题,思路主要集中在两个方向,资源和代码。资源主要在于图片,方法包括移除未被引用的图片,只...

2019-06-27 10:53:15 203 0

原创 otool 分析Mach-O

otool 查看所有的Method otool -v -s __TEXT __objc_methname mach-o的path otool 查看被调用的Method otool -v -s __DATA __objc_selrefs mach-o的path otool 查看所有的Cl...

2019-06-18 15:24:58 340 0

转载 iOS调优 | 深入理解Link Map File

Link Map File初识 我们编写的源码需要经过编译、链接,最终生成一个可执行文件。在编译阶段,每个类会生成对应的.o文件(目标文件)。在链接阶段,会把.o文件和动态库链接在一起。Link Map File就是这样一个记录链接相关信息的纯文本文件,里面记录了可执行文件的路径、CPU架构、目...

2019-06-18 10:57:12 88 0

转载 分析Mach-O文件

OSX系统自带的otool可以分析Mach-O可执行文件 类似命令行工具:jtool 常用命令如下: 查看fat headers信息 otool -f xxx.app/xxx $ otool -f xxx.app/xxx Fat headers fat_magic 0xcafebabe nf...

2019-06-18 10:25:06 63 0

转载 创建CocoaPods的制作过程

使用CocoaPods来管理第三方库实在是方便,在学会了使用CocoaPods后,开始尝试创建一个自己的版本依赖库,当然,迟早要走到这一步的. 创建仓库 接下来实现一个首页广告循环播放功能,项目名为CLRollingCycleView 本地仓库 使用Xcode创建一个CLRollingC...

2019-05-08 16:20:14 72 0

原创 BFTask剖析

github:https://github.com/BoltsFramework/Bolts-ObjC

2019-04-14 22:41:35 151 0

转载 图文翔解HashTree

在各种数据结构(线性表、树等)中,记录在结构中的相对位置是随机的。因此在机构中查找记录的时需要进行一系列和关键字的比较。这一类的查找方法建立在“比较”的基础上。查找的效率依赖于查找过程中所进行的比较次数。 之前我们介绍的各种基于比较的树查找算法,这些查找算法的效率都将随着数据记录数的增长而下降。...

2019-04-10 10:39:50 132 0

转载 mach-o文件分析

一. 先给出一个结构图,大致了解一下内部的结构: image.png 主要结构分成三个部分: Header部分:保存了该文件的一些基本信息,如平台,文件类型,加载命令的个数等 loadCommends部分:根据这里的数据来确定内存的分布 Data部分:存放具体的代...

2019-04-07 13:33:42 186 0

原创 block的变量捕获

先了解一下block的本质 1.block本质上也是一个OC对象,它内部也有个isa指针 2.block是封装了函数调用以及函数调用环境的OC对象 3.block的底层结构如下图所示 为了保证block内部能够正常访问外部的变量,block有个变量捕获机制 变量类型 ...

2019-03-31 13:25:35 78 0

原创 +load方法和+initialize方法的调用

一. load 方法 1.+load方法会在runtime加载类、分类时调用 2. 每个类、分类的+load,在程序运行过程中只调用一次 3.调用顺序 3.1先调用类的+load,按照编译先后顺序调用(先编译,先调用) 3.2调用子类的+load之前会先调用父类的+load 3.3.再...

2019-03-30 23:50:33 89 0

原创 KVC

1. setValue:forKey:的原理setValue:forKey:的原理 注意: 直接给成员变量赋值是不会触发KVO,但是通过KVC修改成员变量是会触发KVO 2.valueForKey:的原理 ...

2019-03-30 17:28:06 82 0

转载 跳跃表原理

最近看了一种数据结构叫做skipList,redis和levelDB都是用了它。Skip List是在有序链表的基础上进行了扩展,解决了有序链表结构查找特定值困难的问题,查找特定值的时间复杂度为O(logn),他是一种可以代替平衡树的数据结构。 下面是skipList的一个介绍,转载来的...

2019-03-29 10:36:29 29 0

转载 Dijkstra 最短路算法

上周我们介绍了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”。本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。例如求下图中的 1 号顶点到 2、3、4、5、6 号顶点的最短路径。 与 Floyd-Warsha...

2019-03-26 10:40:06 56 0

转载 Bellman-Ford 单源最短路径算法

Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法。该算法由Richard Bellman 和 Lester Ford 分别发表于 1958 年和 1956 年,而实际上 Edward F. Moore 也...

2019-03-26 10:15:42 281 0

转载 dijkstra算法:寻找到全图各点的最短路径

dijkstra算法介绍:即迪杰斯特拉算法,是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止,是一种广度优先的搜索方法。dijkstra算法原理:最优子路径存在。假设从S→E存在一条最短路径SE,且该路径经...

2019-03-22 11:42:31 240 0

转载 最小生成树-Prim算法

Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·...

2019-03-21 13:15:38 59 0

转载 最通俗易懂的01背包问题讲解

1、动态规划(DP)   动态规划(Dynamic Programming,DP)与分治区别在于划分的子问题是有重叠的,解过程中对于重叠的部分只要求解一次,记录下结果,其他子问题直接使用即可,减少了重复计算过程。   另外,DP在求解一个问题最优解的时候,不是固定的计算合并某些子问题的解,而是根据...

2019-03-21 11:48:06 203 0

转载 (七)图的邻接多重表存储法(超详细)

前面讲过,无向图的存储可以使用邻接表,但在实际使用时,如果想对图中某顶点进行实操(修改或删除),由于邻接表中存储该顶点的节点有两个,因此需要操作两个节点。 为了提高在无向图中操作顶点的效率,本节学习一种新的适用于存储无向图的方法——邻接多重表。 注意,邻接多重表仅适用于存储无向图或无向网。 邻...

2019-03-20 18:56:46 249 0

转载 (六)图的十字链表存储法详解

与邻接表不同,十字链表法仅适用于存储有向图和有向网。不仅如此,十字链表法还改善了邻接表计算图中顶点入度的问题。 十字链表存储有向图(网)的方式与邻接表有一些相同,都以图(网)中各顶点为首元节点建立多条链表,同时为了便于管理,还将所有链表的首元节点存储到同一数组(或链表)中。 其中,建立个各个链表中...

2019-03-20 16:46:51 422 0

转载 (五)图的邻接表存储法详解

通常,图更多的是采用链表存储,具体的存储方法有 3 种,分别是邻接表、邻接多重表和十字链表。 本节先讲解图的邻接表存储法。邻接表既适用于存储无向图,也适用于存储有向图。 在具体讲解邻接表存储图的实现方法之前,先普及一个"邻接点"的概念。在图中,如果两个点相互连通,即通过其中一个...

2019-03-18 11:49:59 373 0

提示
确定要删除当前文章?
取消 删除