熟悉底层原理,了解flutter,了解一般数据结构
- 图片下采样
- 离屏渲染
- kvo 页面统计加载时间
- LRU算法
- 二进制插桩
- 业务接口合并,重复接口改成内存数据服务,用到的地方还需要读即可。
- load函数迁移
- 废弃class清理
- 让
APP
不立即次崩溃,可以手机崩溃堆栈发送到服务器
CFRunLoopRef runloopRef=CFRunLoopGetCurrent();
while (!dismiss) {
for (NSString * item in (__bridge NSArray *)CFRunLoopCopyAllModes(runloopRef) ) {
CFRunLoopRunInMode((CFStringRef)item, 0.01, false);
}
}
- 利用关联对象存储时间,然后在
+load
调换hitTest
函数,根据点击的时间间隔来判断是否响应该次点击。 jsonModel
利用runtime
和kvc
来实现的KVO
其实内部就runtime
动态生成了NSKVONotifying_XXX
类,重写了获取class
的方法。- 做了一个动态库来记录
method_exchange
的历史记录,需要将该动态库调整到第一个才行。
momeryCache
利用自旋锁/os_unfair_lock
,性能更好diskCache
利用mutex_lock
互斥锁就能满足需求- 读写常用文件需要家读写锁来防止资源竞争
- 读写锁是多读单写,读写互斥。
- FYML 记录方法交换历史
- fishhook原理/冬瓜fishhook原理
os_un_fair_lock
互斥锁,NSLock
是互斥锁
首先遍历
load_com
,找到link_edit
基地址/systab
和dysytab
确认2个section
的偏移量,,然后遍历一次找到symtab
和dysytab
中的符号,将符号指向需要替代的地址。
首先是
image
已经读入系统,然后修改image
中的符号表和动态符号表中的函数地址,指向需要的函数即可。修改之前调用还是直接调用系统函数,修改之后调用自己的函数。因为符号表在
__DATA
段,修改不限制。可以根据自定义函数的地址和section范围来判断是否被中间人
hook
了。
- 为什么分类的方法可以覆盖类的方法?
if (mlist) {
if (mcount == ATTACH_BUFSIZ) {
// attachCategories 追加分类方法 然后调用attachLists
//将后边追加的mcount个数据,挪到了数组前边。
prepareMethodLists(cls, mlists, mcount, NO, fromBundle, __func__);
rwe->methods.attachLists(mlists, mcount);
mcount = 0;
}
mlists[ATTACH_BUFSIZ - ++mcount] = mlist;
fromBundle |= entry.hi->isBundle();
}
- 局部刷新
- 复杂的UI利用分帧刷新处理,首先用一个Container占位,等下一帧开始渲染时候再进行刷新
- 负责图像加入RepaintBoundary,引擎认为足够复杂则会缓存下来
- 列表页包含的数据直接url带入详情页,降低服务端压力
- 内存泄露 利用devtool查看页面实例对象,和native交互的时候不使用feature,使用
void callNative () {
Future future = FlutterBridge. callNative ("method");
_streamSubscription?.cancel();
_streamSubscription = future?.asStream()?.listen((value)
{
do something;
});
}
void onPageDestroy() {
_ streamSubscription?.cancel();
}
- 页面数据的预加载,提高用户体验
一些观察者模式中的订阅者在页面退出时没有取消订阅