有点杂乱,但是知识点还是值得学习的。
2021-01-22
Intel CISC complex instruction set computer 复杂指令集计算机 x86(32位 内存最大2的32次方 为4G),x64(64位,理论内存容量为2的64次方) Intel追求高性能
ARM RISC Reduced Instruction-Set Computer 精简指令集计算机 ARM(32位)、ARM64(64位) x86 ARM追求低功耗
lipo 命令 查看可执行文件 支持的CPU的架构
lipo是管理Fat File的工具, 可以查看cpu架构, 提取特定架构,整合和拆分库文件。
file 命令 查看文件的格式
I386 模拟器针对intel微处理器32位
x86_64 intel x86架构 64位的处理器
armv6 armv7 armv7s 都是32位指令集arm
arm64 armv8 都是64位指令集的arm
苹果A7处理器,支持两个不同的指令集:32位arm指令集(armv6|armv7|armv7s)和64位arm指令集(arm64,armv8)
inline 关键字 是C++的关键字,提高性能,非inline函数在大量重复调用的时候会消耗大量的栈空间。
其与C的define类似,区别是:define仅仅是预编译期间的字符替换,而inline是进入编译期,进行严格的类型检查,比define更安全。
函数体过长,语句过多的inline函数会被编译为普通函数而忽略inline关键字。inline仅仅是建议编译器 将此函数“内嵌”编译,最终还是要看编译器是否采纳。
GNU Compiler Collection,GCC 编译器套装 可以编译C/C++/Objective-C/Java/Fortran/Go等 支持语言范围广
Clang (执行预编译、语法、词法、语义分析)是LLVM的前端,编译C/C++/Objective-C 范围小,但是编译速度快,内存占用小
ld 是链接器 是LLVM的后端 执行链接
事实上,这个过程分解为4个步骤,分别是预处理(Prepressing)、编译(Compilation)、汇编(Assembly)和链接(Linking).------ 摘自《程序员的自我修养-- 链接、装载与库》
LLVM项目是模块化、可重用的编译器以及工具链技术的集合。
本意:low level virtual machine 底层虚拟机
创始人:Chris Lattner,亦是Swift之父
大概是在2011年的时候XCode抛弃了GCC,仅支持LLVM配置编译套件,而在这之前是GCC和LLVM-GCC自由选择配置
Bitcode 是Apple在2015年xcode7时推出的。意义是:源代码被编译为二进制机器码过程的中间表示形态,既不是源码也不是机器码,叫中间代码。
clang -c test.c -o test.o
file test.o
clang -emit-llvm -c test.c -o test.bc
file test.bc
clang -c test.bc -o test.bc.o
file test.bc.o
MD5(test.bc.o)= 70ea3a520c26df84d1f7ca552e8e6620
MD5(test.o)= 70ea3a520c26df84d1f7ca552e8e6620
bitcode 如果设置为true 那么Xcode只有在Archive时才会生效,否则其他的build都不会生效。
或者bitcode 设置为NO,然后在编译选项或者链接选项添加 -fembed-bitcode 是任何build都带bitcode
主App接入第三方SDK,如果主App带bitcode,那么第三方SDK也必须带bitcode
如果第三方SDK不带bitcode,那么主App只能放弃bitcode才能使用这个SDK
App 的完整未压缩大小不得超过 4GB。Apple Watch App 不得超过 75MB。此外,每个 Mach-O 可执行文件(例如,app_name.app/app_name)不得超过这些文件大小的上限
Linux 命令ldd 查看
Mac系统上的 otool 命令 iOS app 逆向的一个工具
otool -L appexec 查看 appexec用到的库
otool -l appexec | grep crypt 查看appexec是否加壳
cryptoff 16384
cryptsize 6651904
cryptid 0
cryptoff 16384
cryptsize 6553600
cryptid 0
cryptid 0脱壳 1加壳 两遍代表支持两种指令集 armv7 arm64
class-dump 反编译可执行文件为头文件 用法 class-dump —arch arm64 -H myMachexe -o myheaders/
MachOView 查看Mac可执行文件结构的软件
yololib 修改Mach-O文件LoadCommands的工具
hopper工具 将mach-o文件反编译为汇编和OC伪代码
dyld工具是负责加载mach-o文件到内存区的。
Mac的
/bin、在系统的环境变量里
/usr/bin、 不允许增删文件
/usr/local/bin 可以增删文件,后在终端里可以立即生效
/etc/profile和/etc/paths是系统级别的,系统启动就会加载
移动安全框架(MobSF)是一种自动、一体化的移动应用(Android / iOS / Windows)静态和动态分析的测试,恶意软件分析和安全评估框架。
nm 命令用来列出目标文件的符号清单
NSArray 可以存储想等的对象 有序的 可通过下标访问元素
NSSet 不能存储相等的对象 无序的 不能通过下标去访问,只能遍历查找
2021-01-25
Linux的系统厂商和包管理工具
CentOS .rpm yum
Ubuntu .rpm apt apt-get
Fedora .rpm dnf
Debian .deb apt apt-get
MacOS的包管理工具
Appstore
HomeBrew 尽量依赖系统现有的组件库,已经存在则不用再次下载编译安装,只处理那些本地不存在的。 下载源码本地编译
MacPorts。 不依赖系统现有组件库,自己有一个完全隔离的目录,存放自己的所有需要的组件,不影响现有系统。下载源码本地编译
文本文件与二进制文件的区别
围观上,存储在介质(硬盘,内存等)都是01存储,都是二进制的,所以在物理上没区别,但是他们的区别是逻辑上的。文本文件是基于字符编码的文件,ASCII码、UNICODE等,二进制文件是基于值编码的文件,文本文件为定长解释,而二进制为动态长度解释
比方文本文件打开时,读取bit流01000000 01000001 01000010,此时第一个8bit按ascii码来解释就是“A”,其他的同理,那么这个文件就可以解释称“ABC” 然后 文本工具软件,就把这些内容打印显示在屏幕上。
Mach-O文件 类似Windows上的.exe .lib .dll等二进制文件 有些是可执行的。
预处理,编译(语法,词法,语义),汇编—>.o文件(机器指令集和),链接—>(多个o文件合体为一个可执行文件)
gcc -P filename.c -o filename.i
将c文件转化成C++文件,这个过程也叫做预处理过程
gcc -S filename.i -o filename.s
将预处理过程生成的.i后缀的文件转化成汇编文件,里面存储的是相应的汇编代码,这个过程叫做编译。
gcc -c filename.s -o filename.o
将汇编文件中的汇编代码翻译成相应的机器语言,这个过程叫做汇编。
gcc filename.o -o filename.exe
这条指令是完成链接这个过程的,它通过链接器ld将运行程序的目标文件和库文件链接在一起,生成最后的可执行文件
生成可执行文件后,我们就能够调用相应的程序了。
g++ 既可以编译c又可以编译c++,而gcc 只能编译c,gcc套件一般包含g++
编译windowsGUI程序 需要带链接标记如下
g++ wintest.cpp -mwindows
2021-01-26
iOS App的状态栏的显隐控制
1、Info.plist文件里有两个配置:
Status bar is initially Hidden:启动闪屏期间 是否需要隐藏状态栏
View controller-based status bar appearance 是否每个ViewController可以定制其页面的状态栏
UIViewController prefersStatusBarHidden
UIViewController preferredStatusBarStyle
2、UIApplication setstatusbarhidden
给原来的类增加属性,不用继承的方式,使用OC的运行时的函数
objc_setAssociatedObject(theObj, (__bridge const void *)(@“myKeyName”), myProperyValueObj,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
iOS的转场动画
1、官方缺省的动画,
UINavigationController 的push 、pop
UIViewController的present、dismiss
2、iOS7开始支持自定义转场动画,需要实现几个回调协议
UIViewControllerTransitioningDelegate
UIViewControllerInteractiveTransitioning
UIViewControllerAnimatedTransitioning
delegate、block的使用场景
1、同一个ViewController里出现多个一样的回调,我们需要通过tag来区分,从而作出不同的响应处理,这样case就比较繁杂。但是,使用了block,紧凑而不用去分tag。
2、单例不能使用delegate,否则,为了通知不同的delegate,需要来回更改delegate。
3、delegate注重过程,block注重结果。
block 存储位置大概有3种
__NSStackBlock__ 栈
__NSGlobalBlock__ 全局
__NSMallocBlock__ 堆
__block int a=10;//可被block内部修改,添加了__block 的self 在MRC下 block内部不会持有外部的self对象,而在ARC下,block内部会持有外部的self对象。
__weak selfClass * weakSelf = self;// block内部使用self,确保block不持有self,避免循环引用
OC的动态性:1编译时不像C/C++那样严格的类型检查以及函数声明实现调用的检查,而是在运行时动态的去查找调用函数。
2可以在运行时动态的给类增、改 属性和方法。
给类的某个实例动态增加自定义属性 注意此处是给某个实例动态增加,同类型的别的实例不会增加,也就是说下面这些objc_开头的都是对obj来说的,而不是对class来说的
objc_setAssociatedObject(ParentObj, @“myPropertyName”, myPropertyValueObj, OBJC_ASSOCIATION_ASSIGN|OBJC_ASSOCIATION_COPY_NONATOMIC);
从实例获取自定义属性
id myPropertyValueObj = objc_getAssociatedObject(ParentObj, @"myPropertyName");
删除某个 动态添加过的属性
objc_setAssociatedObject(ParentObj, @“myPropertyName”, nil, OBJC_ASSOCIATION_ASSIGN|OBJC_ASSOCIATION_COPY_NONATOMIC);
删除所有 动态添加过的自定义属性 慎用
objc_removeAssociatedObjects(ParentObj)//删除ParentObj里动态添加的所有的自定义属性
属性、成员变量
属性指不显式写在类内部的变量。成员变量 指显式写在类的内部的变量。
在类的内存布局中 首先是成员变量,然后才是属性,依次偏移存放,并且注意内存对齐。
内存字节对齐:CPU从内存读取数据到寄存器时 不是一个字节一个字节的顺序读取,这样效率太低,而是从内存中一块 一块的读取,这一块的长度 可能是2/4/8/16/32个字节,不同的系统是不同的。
那么为了满足CPU的这个要求,程序的代码指令在内存上存储时就要按这个要求来存储,所以 对于一个字节长度的变量 在内存中存放时并不是只占有一个字节,而是占有2/4/8/16/32.这就叫字节对齐。
大端 big-endian、小端little-endian
内存中读取一块区域的多个字节,横向排列在寄存器里,内存高地址的子节存放在寄存器最右端 尾部叫 大端模式。
网络字节序指的是大端模式字节序。
以内存高子节结束 为大端。
以内存低子节结束 为小端 ios为小端字节序
在网络传输之前需要进行字节序转换:从小端转换为大端
HTONS(2Byte)
获取类的成员变量列表
Ivar *ivars = class_copyIvarList([BDPerson class], &count)
ivar_getName()
获取类的属性列表
objc_property_t *properties = class_copyPropertyList([BDPerson class], &count)
property_getName()
动态给类的增加实例方法、替换实例方法、交换实例方法。 注意实例方法与类方法 对比。
Method _Nullable class_getClassMethod(Class _Nullable cls, SEL _Nonnull name)
Method _Nullable class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
添加方法会覆盖父类同名函数,但是不会覆盖自己的同名函数
class_addMethods(Class _Nullable, struct objc_method_list * _Nonnull)
class_removeMethods(Class _Nullable, struct objc_method_list * _Nonnull)
交换方法的实现
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)
NSObject的 +load{}方法 是类首次加载到内存时调用的方法
动态性的应用:
1运行时获取某个实例的类型 [obj class],
2判断某个实例是否属于某个类或者其子类[obj isKindof:Class]
3.运行时获取某个实例/类的所有属性列表用于 归档/解档操作。
Objective-C的runtime是 C语言编写的底层API,包括C语言格式的API和结构体类型定义
2021-01-27
id和instancetype的区别
instancetype是Clang3.5后出现的关键字。他们都表示一个未知类型的对象,但是有区别
1、instancetype类型的对象 在编译期确定类型
id 类型的对象 在编译期不做类型检查,因此 id类型的对象 发送任何消息都不会有编译错误。
2、instancetype 只能作为返回值,不能做参数,也不能定义变量
id 既能做返回值,也能做参数,也可以定义变量
3、对于init方法,id和instancetype是没有区别的,编译器会把id优化成instancetype,使用instancetype的好处就是在编译期就能做类型检查:提前做一部分异常处理 如调用某个函数是否合法,使用某个属性是否合法等等。所以,建议自定义的init 返回instancetype类型,而不是id类型。
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0) 指可用的系统版本
第一个指MacOSX系统
第二个指iOS系统
第三个指AppleTV OS系统
第四个指iWatch OS系统
2021-01-28
怀璧其罪
2020-01-30
NSTimer NSRunloop,如果不显式的将NSTimer对象加入到NSRunloop里面的某个Mode里,那么timer函数执行的优先级会比拖拽事件优先级更低:如果2s后执行某个f,那么在拖拽期间(如果拖拽执行了3s),即使到了时间也不会执行f,而是优先等拖拽完成,然后再执行timer的f。
isKindofClass 是不是某个类或者其父类的实例
isMemberofClass 精准判断是不是某个类的实例
NSRunloopMode :NSDefaultRunloopMode、UITrackingRunloopMode、NSRunloopCommonModes
Runtime中具体的方法调用流程
+ (BOOL)resolveInstanceMethod:(SEL)sel{// 1、先给你个机会来动态添加这个函数到这个类上:对所有的实例都有效,添加之后不再走这个函数,只添加一次}
- (id)forwardingTargetForSelector:(SEL)sel{// 2、如果1你不理会,那我再给你个机会,你去找个别人来执行这个函数吧,每次都来走这个函数问一下}
2020-02-01
iOS线程同步
线程同步指的是,多个线程访问同一个资源(变量,函数,语句等等)时之间的协调。也就是一个线程访问的时候,不允许其他线程访问,只有在此线程结束访问之后再让其他线程来访问。
NSLock 内部封装了pthread_mutex 互斥体。哪个线程枷锁,哪个线程释放锁,否则crash。同一个线程对同一个锁,不能连续lock两次,否则crash。
NSConditionLock 内部封装了pthread_mutex互斥体,与NSLock不同的仅仅是,它可以连续多次被同一个线程lock,但是需要进行多次对应的unlock。(场景:递归函数内部使用)
GCD的信号量 主要用于控制并发数。只有并发数为1的时候可以控制线程同步。
iOS的多线程
NSThread 开启的线程默认无RunLoop,需要显式的开启,但是开启之后,
如果确保runloop一直在loop或者在等待,
1、需要在run之前 至少调用一个Source/Timer/Observer
2、或者外围用while(true)死循环确保loop一直在运行,直到有一个Source/Port/Timer/Observer来出发loop执行,
才会真正的让loop开启:有任务执行,无任务休眠线程
GCD相关知识,概念 针对多核运算做的并发计算 软件开发技术
dispatch_queue_t
dispatch_queue_create(“name”,SErial/concurrent)
dispatch_async(queue,^{})
dispatch_sync(queue,^{})
dispatch_get_main_queue()
dispatch_get_global_queue()
dispatch_sempahore_t
dispatch_semaphore_create(cnt)
dispatch_semaphore_signal(semaphore)
dispatch_semaphore_wait(semaphore)
dispatch_group_t
dispatch_release(dispatch_object_t)
2021-02-02
软件设计的6大原则
1 单一职责 低耦合 高内聚
2 依赖倒置 抽象层不依赖于实现。实现要依赖于抽象层。
3 接口隔离 将接口粒度尽量细化
4 开放封闭 扩展性 开放,修改性 封闭
5 迪米特法则 最小知识:
6 里氏替换 要做到用子类对象替换掉父类对象完全ok:不重写非虚函数。
正确性:满足需求,
可扩展:新需求来了,可以平行增加功能模块,而不用修改老的部分
易维护:
可读性:逻辑清晰,语法规范
稳定性,健壮性,
复用性:控件,组件可以重用,避免多次重写代码
可移植性
App性能优化点
1、业务优化,
2、逻辑优化
3、重用UITableviewCell
4、使用不透明背景,避免带alpha的背景做叠加计算导致的性能损失
5、启动屏幕尽量使用App的主页,看上去像启动速度特别快。
6、在后台执行界面无关的运算
7、图片加载用磁盘缓存,内存缓存,用位图缓存,用异步,用多线程。
iOS静态库
.a+.h
.a+.h+资源文件=.framework
纯资源文件=.bundle
动态库 iOS系统库
.dylib
.framework
2021-02-03
GPU 屏幕渲染
On Screen Rendering 将画面直接渲染在屏幕需要的内存区
Off Screen Rendering
卡顿的底层原理:
在一个刷新周期内,如果屏幕上需要的数据无法被准备好(离屏渲染导致耗时较久),那么在用户看来就是卡顿了。
离屏渲染:
广泛的理解:开辟一块内存区,跟屏幕大小相同,然后将屏幕需要的画面绘制到这个内存区,然后等待这块内存区被搬运 贴到屏幕上。
狭义概念:GPU在向frame buffer内存区 一层一层的叠加绘制layer的时候,对与有特殊效果的layer不能直接叠加到内存区,而是需要 到别的地方(离开framebuffer,离屏)进行运算绘制得到最终的效果layer,然后再把这个处理过的layer叠加到framebuffer。那个操作严格意义上才算离屏渲染。
触发离屏渲染的事件,操作:圆角、遮罩、阴影、渐变、光栅化、抗锯齿等
为了避免卡顿,那么就要避免 离屏渲染,方式有几个
静态资源方式
1、采用圆角图片
2、采用圆角遮罩图片遮盖原来的方角图片
代码方式
1、将layer.mask 更改为使用贝塞尔曲线裁剪原控件,然后重新绘制位图,得到圆角位图,这种方式可以避免离屏渲染。
2、使用CAShapeLayer结合UIBezierPath 形成圆角 来遮罩原控件,得到圆角,运算在GPU上,比较快,CPU性能耗费较少。
2021-02-19
获取ipa安装包
使用苹果官方App。 Apple Confiurator 2 更新时 暂停 到临时文件夹里查找
为了确保server端API的调用者是符合要求的调用者 需要每个调用者在调用server的API时自带签名,服务端根据事先的约定验证此签名,符合则放行,否则认为是非法访问,拒绝服务。
签名规则:sign=RSA(Hash(orignaldata));
服务端拿到数据后,做RSA的解密,然后对orignaldata进行hash,然后比对新的到的hash值是否与接收到的hash值相同,相同,则认为数据包未被篡改,否则认为数据包被篡改,是非法数据,丢弃,不做处理。
多线程执行顺序 线程C需要等待线程AB结束后才开始
1、NSOperation addDependency 线程依赖
2、GCD dispatch_barraier_async:在并发Queue上 开启多个asyn异步线程块,然后用barrier_async 异步块 阻塞等待。
3、GCD dispatch_group_notifiy 结合dispatch_semphore 将异步模式更改为同步模式
图片格式
无损压缩png
有损压缩jpeg
无损压缩webp
矢量图svg
位图bmp
Protobuf google出品的类似json的传输格式标准 数据组织是二进制的方式,而不是json的字符串方式,优点:体积小,传输速度更快,解析速度也快。
MMKV 微信出品的类似NSUserDefaults 底层使用的是系统的mmap技术 内存映射
ANR(Application Not Responding) 程序不响应:程序卡死、卡顿
DAU(Daily Active User)日活跃用户数量。常用于反映网站、互联网应用或网络游戏的运营情况
统计:App统计,Web统计。
现有成熟厂商:google统计,百度统计,百度移动统计(iOS、Android)(无埋点<圈选埋点>),友盟统计(iOS、Android)、新秀 神策数据(亮点移动平台的全埋点)
代码埋点 开发者在需要统计的地方加入统计代码来采集信息并上报到server待生成报表
可视化埋点、
全埋点、
无埋点 集成统计SDK后不需要额外增加统计代码,只需关注自己App原有的功能和业务。
圈选埋点:App运行后通过界面上的触摸来 增加埋点,前提需要App内部做了触摸响应的处理。
用于统计页面的展示次数和时常,用于统计用户的行为
便于对App进行针对性的优化,给产品和运营提供有力的数据支撑。
Web服务器 提供输出静态HTML的服务器 Apache 、httpd等
提供解释 执行逻辑的服务器 Tomcat(可以解释执行servelet、jsp),然后配合apache输出html给客户端浏览器
应用服务器 自己写的服务程序 一般c/c++编写,或者其他的语言都可以,只要编写后的程序提供服务给别的应用程序,我们就把这种程序叫做应用服务器。
比方:我们写的IM服务器就是应用服务器,主要用于服务IM客户端应用程序的。或者自己写的文件服务器,主要用于客户端应用程序与服务端文件的交互服务。
HTTP 端口80/8080
FTP端口21
SSH服务端口22
TELNET服务23
一个进程可以绑定多个端口号 多个socket
但是一个端口号只能对应一个进程,所以开启端口前需要先检测端口是否被占用。
0-1023 为约定俗称的端口号区间,一般不能随便使用
1024-65535 为系统随机分配端口号的池子,分端口号给客户端程序使用。如果作为服务程序那么需要自己在这个区间选择一个未占用的端口号
Cat、more、less 查看文件。
more less 支持翻页 退出命令为 ctrl+c/z,
下一页:空格
上一页:ctrl+B
查找命令 ./searchtext 回车 p 回到开始,n指示下一条
NSString 的copy和strong 的区别 如果是不可变字符串 那么都不在分配内存,只是记数+1,如果是可变字符串,那么copy会生成一个新的对象。而strong则仍是记数+1,性能上来说strong更快,不用判断是可变与否,直接记数+1.
抓包工具:Wirshark、Charles、CocoaPacketAnalyzer,tcpdump 等。
常见的过滤规则 host、 ip、port、等等
iOS 抓包方式
1、PC建立WiFi热点,让iOS设备连接到这个热点,然后在PC上抓包,缺陷:不能抓手机的流量包
2、使用rvictl工具,Xcode command line tools 自带
iOS 5后,apple引入了RVI remote virtual interface的特性,它只需要将iOS设备使用USB数据线连接到mac上,然后使用rvictl工具以iOS设备的UDID为参数在Mac中建立一个虚拟网络接口rvi,就可以在mac设备上使用tcpdump,wireshark等工具对创建的接口进行抓包分析了。优点:方便,WiFi/2/3/4G数据包都能抓取
命令行敲入
建立连接 rvictl -s deviceuuidstring
查看 ifconfig rvi0
断开连接 rvictl -x deviceuuidstring
socket()
bind()
setsockopt()
connect()
非自由程序:一般指商业软件
LGPL:公共函数库许可证 LGPL 使用了LGPL协议的开源库,商业软件可以不用开源代码,并且可以销售。
GPL :只要使用了GPL协议的开源库,那么无论开发什么软件都要开源代码 并且免费
BSD/MIT 协议 开发者对遵循了BSD/MIT协议的开源软件可以 为所欲为
Instruments 辅助分析套件
Leaks 查内存泄漏
System Trace 查启动缺页异常次数
Time Profiles 中的 Profile 可以方便的分析模块中每个方法的耗时
二进制重排:在Mach-O文件中重新排列函数的存储顺序,以便于载入内存时尽量减少PageFault开销,从而优化启动速度,达到最快。
1、启动优化:
PageFault :缺页异常 出现后,系统会从磁盘读取对应的数据所在块,按虚拟内存页来加载到内存中,每次缺页异常总计耗费时间大概0.7ms。
所以,如果启动时,执行的缺页异常(启动需要的内存数据<代码、数据、资源文件等等>)操作比较多,那么耗时也会比较多,表现出来的就是启动非常慢。
(1)查看启动时的PageFault开销—Instruments->system trace->main thread ->Summary Memory:Virtual Memory->File Backed Page In xxx
(2)查看Mach-O文件的函数排列顺序:编译配置增加 Write Link Map File :yes,然后Build一遍
在生成的app所在的目录的上一层 Intermediates.noindex->myproj.build->myproj-LinkMap-normal-arm64.txt 即为Mach-o最终内部的函数排列顺序。
(3)测试更改排列顺序,让启动需要的函数尽量排列在一起
静态库文件.a就是一组.o文件的ar包,可以用ar -t查看.a包含的所有.o。
运行时 环境变量设置为 DYLD_PRINT_STATISTICS 1/YES。那么 启动App会看到一些时间报告
pre-main time: 1.3 seconds (100.0%)
dylib loading time: 161.47 milliseconds (12.2%)
rebase/binding time: 25.11 milliseconds (1.8%)
ObjC setup time: 444.37 milliseconds (33.5%)
initializer time: 691.82 milliseconds (52.2%)
c++的重载(overload)和重写(overwrite) 覆盖(隐藏)
重载和重写的区别:
(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中。
(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。
(3)virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有。
隐藏和重写,重载的区别:
(1)与重载范围不同:隐藏函数和被隐藏函数在不同类中。
(2)参数的区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写。
c++的动态性(多态)指的是什么
编译时的多态:通过重载函数或者运算符实现编译时多态,相同的函数名,不同的参数类型或个数 使得同名函数有多个实现状态,叫编译时的多态。
运行时的多态:通过子类重写父类虚函数,在用父类指针指向不同字类对象时,调用不同实现的同名函数,叫动态多态性。:用一套代码逻辑实现不同的效果。
NSDictionary 是HashTable:不允许key出现相同的对象的情况,否则value会出现覆盖。HashTable的原理就是 使用key通过hash算法获得一个整数值 作为下标,来通过数组下标访问,提高速度。
HTTP协议 属于应用层协议
请求报文格式
请求行:方法+url+版本号。 GET /index.html HTTP/1.0
HTTP头部:主机域名 HOST
Connection Range User-Agent Acceptxxx Contentxxxx
HTTP实体:body
响应报文格式
状态行:状态码 2xx 服务器已接受。3xx跳转,需要客户端再次请求 4xx请求出错 5xx服务器内部出错。
HTTP头部:Content
HTTP实体:body
浏览器 输入网址后 会车 到页面出现 所经历的步骤
1、浏览器做网址检测:是不是合法的网址格式,如果不是直接报错
2、浏览器默认补齐http协议格式网址。
3、浏览器咨询本地DNS服务:查找IP地址,先查找DNS的缓存表,然后查找本机的host映射表。
4、如果没有,那么请求DNS服务器,查找IP地址
5、首先向网关发送包:如果不知道网关地址,还需要ARP协议,先走一遍获得网关MAC地址。然后出关。
6、数据包经过传输到大DNS服务器,DNS服务器在自己的Cache表里查找这个网址对应的IP,找不到就去自己的DNS服务器去找,直到最后。
7、
“翁龙满杨”便是翁家山村青明山、龙井村狮峰山、满觉陇村白鹤峰、杨梅岭村百丈坞等主要山头
fishHOOK 可以HOOK住OC函数,也可以HOOK住C函数,注意:此处的C函数为可执行文件调用的外部模块的函数(c库,别的第三方库等)
原理就是:在运行时 动态更改函数符号表(Non-Lazy Symbol Pointer、Lazy Symbol Pointer)我们更改的是懒加载的符号表内容,使得被调用函数地址更改为自己定义的函数地址,从而达到HOOK函数的目的
使用的工具为MachOView、fishhook.h/fishhook.c 、Xcode、LLDB
使用的调试命令:image list(查看依赖的image模块)、dis -s 0x12345678(查看内存地址存放的内容)、
Image叫做内存镜像文件:磁盘有一份,内存载入一份完全一样的,就像在镜子里看到的一样,所以内存这份叫做镜像文件。
加壳:就是编译之后的二进制代码,进行加密处理,使得别人无法看懂指令。
脱壳:就是把加密之后的二进制代码,还原为cpu可以读的指令集,就代表还原为汇编代码(因为汇编代码与指令代码一一对应)
脱壳的方法:加载程序将加密后的可执行文件载入内存后,有一个对应的image内存镜像文件,此时是原封不动的载入内存,但是cpu对于加壳之后的进行了混淆加密的二进制无法读取运算,所以,此时会进行一个脱壳:还原为cpu可读取的二进制,此时,我们将还原后的二进制行文件dump出来,那就完成了脱壳,此时可执行文件就成了为加密的直接反汇编的程序。此时,我们可以对其进行逆向研究和更改。
Aspects框架详解—用hook方式截获OC函数,进行自己的代码,然后再执行原来的代码
2021-03-10
类别/分类 Catogery
扩展 Extension
类别:对已有的类进行方法扩展,不能增加属性
扩展:一般写在类的implment的头部,作为私有区域,可以有属性和方法,均作为类内私有,不暴露在.h文件中
在内存模型上的区别:类别更改了函数表,而没有更改类的属性区域
类别是运行时改变函数表,而扩展是在编译期改变类的结构(属性区和函数表区)
Hash 散列算法:输出的值是有限的,而输入是无限的,所以,必然会有不同的输入得到相同的输出
签名:sign=RSA(Hash(rawData))
2021-03-15
init:内部调用initWithNibName 传入空参数
initWithNibName:延迟加载,有对应的类代码
loadNibNamed:即时加载,没有对应的类代码