https://blog.csdn.net/tfy_2425482491/article/details/75214148 dispatch_source实现可取消的定时器 多线程代码练习 各种存储方式代码联系 coredate 代码联系 runtime代码联系 65 runtime常用方法练习 runloop代码联系 70 线程安全的单利模式代码
1.utoreleasepool的理解 2.nonatomic 与atomic atomic 原子的,在多线程中,可以保证set方法和get方法的完整性,并不能保证县城的安全性,nonatomic 非原子的
3.category 和extension 区别 category 分类,运行时决定,只能添加方法和属性,协议,不能添加实例变量
extension 扩展,编译时决定,默认是私有的,在.m文件中实现,可以添加方法,属性,实例变量
category 分类中的方法与类中的方法同名,优先分类中的方法,方法可以被子类继承,对于扩展一个类的实现方法中,分类比继承好,因为不会改变原有类与其他类的关系
分类 category实现原理 1.category底层结构是结构体category-t 存储分类的对象方法,方法,属性,协议信息,(所以不能添加成员变量),在运行时runtime将分类的数据合并到类中
4.mrc内存管理,原理,黄金法则,内存泄露 如何避免内存泄露(避免循环引用,及时释放,懒加载) 5,循环引用产生的情况及处理 tableview block timer
6.block oc对象,封装的是一段可执行代码,self。block会让self 强应用block 但block内部会用到self。。会导致block强引用self,解决办法,在block 外部使用——weak 声明一个weakself 内部局部使用__strong 声明weakself
7 WKWebview:与UIWebview 占用内存更小,响应速度更快,有加载进度条 js调用oc 方法使用self,wkwebview,configuration,usercontentcontroller addScriptMessageHandel 添加 oc 调用js evaluateJaveScript
8 ,。多线程 NSThread GCD NSOperation
从子线程回到主线程的方法有
performSelectOnmainThread
延迟执行方法
performSelect onthread
gcd 回到主线程 dispatch -Get——main_queue
9.子大于父。如何在超出父视图的区域让子相应点击事件 父: 重写方法hittest withEvent 并调用所有子的hittest Withevent 返回最能处理事件的子,
10.扩展button的点击范围 方法1: 添加分类category重写pointEvent WithEvent 方法2: 添加category重写 hitTest WIthEvent
oc 内存管理在实际中的应用 1.UItableview 数据过多 2.有透明度的view 设置opaque为yes 3.避免多个xib 4.主线程 5.加载本地图片,尽量保持大小一致,缩放很耗资源UIScrollview 下载网络图片。开启子线程缩放图片,然后加到UIImageview上 而且使用本地图片注意imageNames会缓存图片,所以如果只用一次,使用imageWithContentOfFile方法 6.选择合适的数据类型
7 利用缓存, 8 处理内存警告
11.循环创建变量是用autoreleasepool
GCD 队列 Dispatch_queuet 任务 block表示 主队列异步 一个一个执行 朱队列同步 死锁 不执行
12 tcp udp socket 长短链接
13 应用程序生命周期: willFinish(启动) didFinish(入口。只执行一次) willResignAction(切换到非激活状态,比如home) didBecomeActive DidEnterBackground WillenterForeground willTerminate (程序退出)
app启动过程 打开程序-执行main函数(UIApplicationMain初始化,设置代理,开启主线程runloop,创建主线程的自动释放池)--监听各种系统事件,并通知AppDelegate的相关代理函数,--- 最后程序结束,
runloop 定义,作用,实际应用(控制线程的生命周期,NSTime滚动刷新UI等)
ios 核心动画: 两大类:隐式动画和显式动画
隐式动画,系统自带的,一直存在无需手动关闭的;指发生在CALayer改变(如layer的各种属性值,或者图层书的改变),只要能产生layer属性的变化都会自动产生动画,
隐式动画 是有系统自动创建,我们无需任何设置,系统会自动觉得如何进行,何时进行
调用方法1.使用CATransaction的begin commit 2.使用老方法UIView beginAnimations context commitAnimations(实际与CATrasaction类似) 3.使用block调用 UIView AnimateWIthDuration : options :animations:^{} completion:^()
动画可以修改的值 位置形状 (frame bound cener) 色彩(alpha color) 角度(transform 旋转角度)
显式动画,不存在,需要手动创建,自然也需要手动关闭 链条和数组的区别
1.存储形式“ 数组是连续空间,且确定长度, 链表一块可不连续的动态空间,长度可变,每一个节点保存相邻节点的指针
数据查找: 数组是线性查找。可以直接使用偏移地址,速度快, 链需按顺序检索节点,效率低 3.数据插入和删除 链接可以快速插入和删除节点,数组需要移动大量数据, 4.越界问题,链表没有,数组有
总结: 数组便于查询,大小固定,相对节省空间,链表便于插入删除,可随便变长,但占用更多空间。
https请求的网络连接中,输入账号密码登录,请求到达服务器之前经历了什么?
1.客户端打包请求。 包括url 端口,账号密码等信息,一般采用post凡是放入请求的body中,因为是https所以还需要加密信息模块,相当于客户端请求钥匙,然后使用钥匙加密数据在发送请求,所以真正发送数据之前,先发送的请求时请求钥匙, 2,服务器接收请求 客户端的请求一般先到达一个DNS服务器,将网络地址解析为ip地址后,信息就到达服务器端,此时客户端和服务器就建立一个socket链接, 3.服务器返回数组证书 4.客户端生产加密信息 收到服务器的数证书后,客户端会根据它生成钥匙,将要发送的信息进行加锁加密 5.客户端发送加密信息 6.服务端解锁加密信息 7服务器端向客户端返回信息 8.客户端解锁返回信息,客户端收到服务器的返回信息后,使用生产的钥匙进行解密
load 与initialize load 类被引入项目时就会自动调用,且只调用一次,会自动调用【super load】,调用顺序优先于category,多个类别均实现load,则调用顺序不确定,但与类别在compile source 中出现的顺序一致
load 是线程安全的
Initialize是在类或者子类的第一个方法被调用前调用,系统自动调用,无需显示调用【super initialite】多个category的initialize会覆盖类自身的initialize方法
多线程死锁如何产生,死锁原因 死锁产生原因: 资源不足,线程推进顺序不对,资源分配不当 死锁产生条件 1 互斥(进程独占资源) 2.请求与保持(进程请求资源是,对已有资源保持不放) 3.不剥夺条件(已获取资源不可强行剥夺 ) 。循环等待条件(收尾相接的资源等待关系)
在gcd中,主要的死锁是当前的串行队列里面同步执行当前串行队列,解决的办法是将同步的串行队列放到另一个现场执行
oc多态实现原理 1.oc每个类都有自己的命名空间,类中的名称和类外的名称不冲突,所有不同的类可以有相同的方法名
消息发送机制 【obj func】编译器自动转化为objc-msgSend(obj,func),这一步叫消息发送,然后进入消息传递流程 通过isa指针找到类 1.在类的方法cache 2,方法列表中查找,找到加入方法cache 3.找不到,super_CLASS的方法列表中查找,找到加入cache中 4.自身及所有父类中均找不到,则 进入动态消息转发流程
消息转发流程 1.添加动态消息解析,需实现代理resolveInstanceMethod方法 2.添加备用接受者,需实现代理 forwardingTargetForSelector 3.完成消息转发,实现代理方法methodSignatureForSelector 获得函数签名,,runtime自动创建一个NSINvocation对象发送forwardInvacation消息,
这一步返回nil则runtime发出消息doesnotRecoginzeSeletor消息会直接挂掉,
使用runloop让现成常驻 gcd异步创建NSTimer ,timer加入runloop中,启动runloop
野指针:指针指向的对象已被回收 僵尸对象:一个已被释放的对象,这个对象所占的空间没有分配给其他对象使用,这个对象就是僵尸对象 指针设置为nil。调用对象的方法,不会发生任何事情
打开xcode的僵尸变量机制 dia果农实体超市中的enable zombie objects
物理地址:物理内存上的32位地址 虚拟地址:虚拟内存中地址 逻辑地址:上层程序员操作的地址,也就是虚拟地址中的段偏移地址 线性地址:虚拟地址进行分段后得到段基址,段界限,段偏移地址。 段基址和段便宜地址的组合就是线性地址 虚拟内存:对物理内存对应,一般是物体内存的2到3倍,是计算机的一种技术,会暂时一些数据存储到外部的磁盘存储器上,在需要时进行数据交换,可以让计算机运行别实际内存大很多的程序
ios 性能优化 main函数之前耗时操作: 动态库加载,objc类数量,c++静态对象 ,objc 的load main函数之后的耗时操作: main函数耗时 applicationDidFinished rootViewController及其子视图的加载
main函数之后的优化: 1.不影响首页展示的服务放入子线程处理,或者延时处理,懒加载 2、使用首页数据本地缓存,优先用本地缓存数据,
MVVM 与mvc 多了一个ViewModel,而且viewmodel是为view的量身定制的, modle vm=viewModel v= v+c viewmodel 网络请求,返回数据逻辑和缓存读写 model 用于数据模型化 MVVM的核心是双向绑定,绑定的意思是两个对象建立关联,其中一个改变另一个自动跟着变
双向绑定的实现: 1.controller拥有view 和viewmodel viewmodel拥有 model 及controller的弱引用 controller 或者view 会接受来自viewmodel的model改变的通知 2.用户点击。controller 会让viewmodel其请求新的数据,viewmodel请求后保持数据模型,从而实现model的更新。实现v绑定m 3.vm在model改变后会view controller发送一个通知。从而其根据新的model更新view。这就实现了m绑定v
viewmodel的职责: 1封装业务逻辑处理 2,封装网络处理3, 封装数据缓存
属性引用self.xx 和_XX的区别
@property声明的属性,会产生一个_XX的成员变量,还有对应的set get方法
self.xx 会调用属性的set方法 _XX 访问的属性对应的成员变量 xcode4.4之后。@property已经具有的作用有: 1.生成get set 方法声明 2.生成私有个————xx属性对应的成员变量 3.生产set get 方法的实现
frame :view 在父视图坐标系下的位置和大小 bounds :view 在自身坐标系下的位置和大小
如何让类可用copy修饰符 1,类需要遵守NSCOpying协议 2.类实现NSCopying协议的方法CopyWIthZone { object copy = 【【【self class】 allocwithzone】init】 copy-》name = 【_name copyWIthZone:zone】;
} NSInterger:是int 或者long的别名,会自动根据系统是32还是64来决定自身是int还是long int:c语言基本数据类型,占4个字节 NSNumber:oc的数据类型,是class。创建后便是对象 byte 一个字节 char 一个字节 bool 一个字节 short 2个字节 int 4个字节 float 4个字节 long 8个字节 double 8个字节
id对象 特性:id声明的对象具有运行时的特性,即可以执行任意类型的oc对象
————Bridge(仅仅完成类型转化,不转化内存管理方式)
_bridge_retained oc 对象转化为cf对象(添加了retain操作,防止cf对象的提前释放)
————bridge_transfer 用于cf对象转oc对象(转移cf对象的所有权,使用oc的arc)
对称加密: 需要对加密和解密使用相同密钥的加密算法
DES: 标准加密标准,一种适用密钥加密的块算法 AES:高级加密标准,在密码学中有成Rijndael加密法 ECB:将数据分成若干相同的小段,对每一段进行加密 CBC:将数据分成若干相同的小段,然后每一段加上初始段或者上一密文进行加密
分类有名字,类扩展没有名字。是一种特殊的分类
为什么学习网络编程 网络编程是一种实时更新应用数据的常用手段,网络编程是开发优秀网络应用的前提和基础
网络基本概念 客户端 :手持设备上的app 服务端 请求: 响应 数据库 URL:统一资源定位符, 协议/IP地址主机/路径 路 径是资源在主机的具体位置 常见请求协议 【file】 访问的是本地计算机上的资源 【ftp】访问的是共享主机上的文件资源 【mailto】访问的是电子邮件地址 【http】超文本传输协议,访问的是远程的网络资源
ios中http请求的实现方案 原生方案 1.NSURLConnection 2.NSURLSession 3.CFNetwork(底层的,c寓言级别的)
第三方框架 1.AFNetworking 2.ASIHttpRequest 3.MKNetworkkit
服务端常见错误码 【200】请求成功 【400】客户端语法错误 【404】无资源 【500】服务器内部错误请求
谓词: coredata中查询删除等的逻辑过滤条件 NSPredicate
https: 以安全为目标的http通道,是http下加入了ssl层,存在不同与http的默认端口和一个加密/身份验证层
https与http的区别 1.https需要到ca申请证书,需要花钱 2.http是超文本传输协议,信息明文传输,https是具有安全性的ssl加密传输协议 3.二者使用不同的链接方式,http默认端口80 https默认端口443 4.http的连接简单,而且是无状态的,https是有http + SSL 构建的可进行加密传输,身份认证的网络协议,更安全
url中文乱码问题(UTF8转码即可) 使用string stringbyAddingPercentEscapesUSingEncoding:NSUTF8StringEnding
LRU: 一种常用的缓存淘汰算法,核心思想是优先那些最长时间未被访问的数据, 通常是结合了哈希表和双向链表来实现的,哈希表用于快速定位数据,双向 链表用于表示数据的使用顺序,当一个数据被访问时,它回被移到链表 的头部,表示最近使用过,当换成满时,会移除掉链表尾部的数据,因为这些数据 最长时间未被访问的
delegate notification KVO 常见锁 @Synchronized(self)
NSLock NSRecurSiveLock 递归锁 NSConditionLock 条件锁 dispatch_semaphore gcd的信号量
kvc 底层实现
调用setValue
检查顺序 key的set方法 _key 成员变量 属性key
都找不到则会调用valueforUndefinedKey
和setValue forUndefinedKey,需要我们自己去重写,否则会崩溃
kvo内部实现原理 基于runtime 机制实现的,当属性第一次被观察时,创建这个类的派生类,并重写方法setter方法实现真正的通知机制 类名为person,则派生类名为NSKVONOtifying_person.第一次属性被观察时,系统会自动将isa指针指向派生类NSKVONotifying_person, 会自动调用派生类中的方法 WIllChangeValueforkey 和DidChangeValueForkey,最后调用observevalueForkey来通知观察者,属性发生了变化 因为ios在底层,重写了class方法,所以会让我们以为调用的当前类,从而达到因此派生类的目的
oc 中的发射机制 1) class 反射 :指的是类名之字符串之间的互相转化 NSClassFromString NSStringFromClass 2)SEL 发射:指的是字符串和方法的互相转化 NSSelectFromString NSStringFromSelector
const:修饰限制,被修饰的变量是只读的 static: 修饰局部变量,只会产生一份内存,延长其生命周期,在程序结束时销毁; static 修饰全局变量,使全局变量只能在本文件中访问,而且避免重复定义全局变量
static 与const 联合起来声明一个只读的只能在一个文件中使用的静态变量 extern const 多个文件共享的只有一份的全局变量
inline: 内联函数 ,用于替代宏 inline 内联函数与宏的区别
宏定义不是函数,只是使用起来像函数,不会做类型检查,是不安全的。 宏函数是在预编译的时候把所有的宏名用宏体来替换,就是简单的字符串替换,不会
内联函数: 本质上是一个函数,定义必须在声明之前,不能使用while for等复杂的控制语句。 是在编译的时候进行代码插入,会进行类型检查,调用时会直接原地展开,避免了普通函数调用的call指令的开销,提高效率。
nil: 对象为nil,系统会收回内存
Nil == nil。习惯用于类置空用Nil
NULL 空指针
【NSNUll null】 意思是值为空的对象,是一个有效的内存地址
nil是一个空对象,内存已在系统中消失
layer 和UIView CAlayer与UIView是相互依赖的关系,每一个UIView内部都有一个对应的CAlayer(成为backing layer)
Calyer继承于NSObject 不响应事件,只负责显示UI,提供了一系列属性来控制视觉效果和动画,用于内容回执
UIView继承与UIReponder负责用户交互(接受并相应时间),是对CALayer的底层封装,
id: 不能再编译的时候判断对象的真实类型,可用于定义变量,返回值,形参
instancetype在编译时就可判断对象的真实类型,只能用于返回值,
NSObject * 是有类型的,与id一样都包含了一个Class isa指针定义
init方法中id与instancetype是一样的,但返回值必须用id
Isa指针:是一个Class类型的指针,每个实例对象都有,用于只想对象的类
Class 也有isa指针,指向Metaclass元类,元类也是类,
对象 ---- 类 ---- 元类 ---- NSObject , NSObject 指向自身
[gc class]; 【gc alloc】.class ; object_getCalss([GC alloc])
三者的地址相同,说明NSObject只有一份,即 根元类(NSObject)在内存中只只有一份,因为类的信息在内存中也只有一份,所以类对象只有一份
isa走位和继承关系图
isa指针走位 实例对象(instance of class)的isa指向类(class), 类(clsss)的isa指针指向元类mateclass, 元类的isa指针指向根元类,跟元类就是NSObject的元类 跟元类isa指针指向自身,形成闭环
isa只一个Class类型的指针,
类之间的继承关系 1.类class继承自父类superclass, 父类继承自根类RootCalss,根类就是NSObject NSObject继承自null
元类mateclass继承自父类的元类meta superClass
父类的元类meta superClass继承与跟元类(Root meta class)
跟元类root meta class继承自根类RootClass 。这里的根类是NSbject
class方法: 用于获取对象所属类的实例方法,是由NSObject的类定义的。 1.类对象:class 方法返回的指向对象所属类的指针,叫做类对象,类对象是一个表示类的数据结构,包含类的相关信息 2.远行时类型识别(RTTI):指的是同class方法,在运行确定对象的具体类型 3.集成关系, 无论是基类指针还是子类指针,调用class获取的都是对象所属的实际子类的对爱那个 4.元类metaclass,类对象本身也是一个对象,是元类的实例。
如何访问一个类的私有属性
1,KVC setValue ForKey 通过属性名称访问
2.runtime 可以获取累的所有属性,自然包括私有属性
isKindofclass: 某个对象是否属于或者继承与某类型 isMemberOfcalss: 某个对象确切属于某个类型 selector: 通过方法名,获取在内存中函数的入口地址
layoutSubViews的作用和调用机制
layoutSubviews作用: layoutsubviews是对subivews的重新布局(比如更新子视图位置),默认是不做任何事情的,需要用到的时候要在子类重写 layoutsubviews 调用时机 1、 setLayoutSUbviews会直接调用 2.addSubviews; frame发生变化; 第一次滑动scrollview; 旋转screen; 四中情况会触发layoutSubviews 3.改变UIView大小会触发父UIVew的layoutsubviews
init 不会触发layoutsubviews
intiWithFrame 且rect不是CGRectzero时会触发layoutsubviews
setNeedslayout: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,但不会立即刷新,
layoutIfNeeded :如果有需要刷新的标记,会立即调用LlayoutSubviews。没有标记就不会调用
block本质: block本质是一个oc对象,封装了函数调用及函数调用的oc环境 block有三种类型: NSGLobalBlock :没有auto变量的block都是globalBlock,存放在数据区,也就是.data区
NSStackBlock:如果访问了auto变量就是stackblock。存储在栈区。会自动销毁无法跨函数访问
mallocblock 在ARC环境下,程序运行时会自动对stackblock进行copy处理,得到一个mallocblock,所以开发过程中使用的一般都是mallocblock
block copy: block作为函数返回值; 复制给——strong指针; usingBlock函数的参数; GCD 中API的方法参数 都会发生copy行为,从而变成mallocblock
__block: 一个修饰符,用于解决block无法修改auto变量值的问题
但__block不可修改全局变量和static变量
编译器会将__block变量包装成一个对象,这个对象有两部分组成:
一个指针__Block_byref_age_0 *age。指向生成的对象
一个指针用于存放age的值
修改age值的过程
1.通过block内部的__Block_byref_age_0 找到_block变量生成的对象,(底层是结构体)
2.在结构体中找到age
3.对age进行赋值操作
如果在block中修改局部变量的值 方法1:用static修饰局部变量 方法2,局部变量修改为全局变量 方法3:用__block修饰局部变量
block解决循环引用的方式有三种: 1.weak: 不会产生强引用,指向的对象销毁时会自动让指针置为nil 2._unsafe_unretained 与weak类似,但销毁时不会自动置为nil 3.__block 修饰则必须调用block对象如(person.block())。在block中对象person置为null
BAD——ACCESS 出现在访问了野指针的情况下,就是访问已经释放对象的变量或者方法
lldb(gdb)常用调试命令
.p 打印指令是print的缩写
.po 打印对象指令
.bt打印堆栈
ios常用的数据存储方式 NSUserdefault NSKeychain NSKeyedArchiver, 写文件 sqlite FMDB Coredata
NSUserDefault 存储用户配置信息,实际上是存储在沙盒下的.plist 文件
2.NSKeyedArchiver 归档存储,实在沙盒下的一个文件,是一次性存储一次性解压,每次修改,都需要全部解压,然后存储 3.数据库文件,比如coredata sqlite。 FMDB
文件存储,就是写文件write,依然在沙河下
NSKeychain:最安全的存储容器。是所有app之外的sqlite数据库
ios的沙盒目录 .Application 存放源程序代码,上架前会经过数字签名,上架后不可修改 .doucument 常用目录,icloud的备用目录,可存放数据 .Library :1) Caches 缓存目录,一般在更新应用时会清理 2)Preference 设置目录 .tmp 存放临时文件,随时又被清理的可能
ios的多线程技术?pthread NSTHread GCD NSoperation
GCD从子线程回到主线程写法 Dispatch——Sync(dispatch_get_main_queue())
gcd同步若干个异步调用 使用gcd-group实现 diaptch_group_async(grou,queue) dispatch_group_notify()
dispatch_barrier_async(栅栏函数)作用: 1.在它前面的任务执行结束后它才执行,在它后面的任务要等到执行完成后才会开始执行。目的是避免数据竞争
dispatch_async dispatch_barrier_async
Rooloop的六中状态
KCGRunLoopInter 进入runloop循环 KCFRunLoopBeforeTimers KCFRunLoopBeforeSources 处理input sources事件前回调 KCFRunloopBeforeWaiting runloop睡眠前调用 KCFRunloopAfterWaiting runloop 唤醒后调用 KCFRunloopExit 退出runloop
runloop位于coreFoundation库中,而coreFoundation位于core Service层中 coreFoundation是跨平台通用库,支持mac ios windows
CFRunloop 与NSRunloop是可以互相转化的
runloop 功能 1。runloop使线程保持忙碌(有事做)和休眠状态(无事可做)见切换,由于休眠状态的存在使现场不至于意外退出,保持常驻 2.runloop提供了处理事件源(source0, source1) 3.runloop提供了处理timer 4.runloop自身会在多种状态间切换(exit,run sleep等)。并在切换时通知所注册的observer,使系统做出对应的操作
source1 是由runloop内核管理,会自动唤醒runloop source0 主要是应用层的事件。如UIEvent。选哦手动调用signaled来唤醒runloop
runloop跟线程的关系 runloopMode:
常用的timer 1.NSTimer 或者performSelector : afterDelay产生的timer。二者都是有runloop处理,实际结构是CfRunloopTimerRef 3.GCDTimer(有gcd自己处理,无需runloop) 4.CADDisplayLink(通过向runloop投递source1 实现回调)
Observer 作用是让外部监听runloop的运行状态,从而在不同的时机做不同的事情。系统在app启动时。想mainRunloop中注册两 两个observer。 第一个observer监听的事件是Enter(即将进入runloop), 第二个observer监听 beforewaiting 和Exit两个事件。beforewaiting 会释放旧的自动释放池并创建新的自动释放池。exit会释放自动释放池
runtime常用方法 1.class_copyMethodList 便利所有方法列表 class_copyIvarList 所有属性列表 class_getInstanceVariable 获取指定名称的成员变量
ivar_getName获取成员变量名
ivar_getTypeEncoding
object_getIvar
object_SetIVar
object_msgSend
runtime常用应用 更改属性值 动态添加属性 动态添加方法 交换方法实现
拦截并替换方法 在方法上添加额外功能 归档解档 字典转模型
Objc_msgForward 是IMP类型,用于消息转发,当向一个对方发送一个消息,如果这个消息没有实现,runtime就会触发回调objc_msgForward
静态库和动态库的区别
静态库:(.a) 1。模块化。分工合作,可重复使用(不是共享) 2.静态库在程序编译时会被链接到目标代码中,所以任何改变都会重新编译,而且链接时会完整的复制,锁哦一多次使用会有多份拷贝
3.在程序运行时经不在需要静态库, 4.静态库有优化linker的优化选项,会剔除所有它认为无用的代码。
如何关闭静态库的linker优化? Other Linker flags 添加-Objc 和-all_load
动态库(.framework)
1.使用动态库,可缩小可执行文件体积,可多个应用共享内存中的同一份动态库文件
2.动态库在编译器不会链接到目标代码,在程序运行时才会被载入,因为运行期间需要动态库。
3.使用动态库,可以不重新编译链接到可执行文件的前提下,更新动态文件库来达到更新应用程序的目的。
静态库和动态库共同点
1.静态库.a 自身是二进制文件,需要与.h 及其他资源文件才可使用 。 动态库.framework 自身就包含了二进制文件.h 其他资源文件
2.图片资源一般都单独放到一个.bunder文件中,做法是:新建文件夹,放入图片资源,然后命名为 **.bundle即可 3.静态库,a中的category有时会找不到调用方法(错误 selector not recognized),只需要把 Other Linker flags 添加-Objc即可 4.静态库不要暴露过多的.h文件,如果实在没办法,可以新建。h文件,然后再它里面包含所有需要暴露的,h文件,最后暴露这一个。h即可
伪代码: pseudocode 是一种非正式的,类似于英语结构的,用于描述模块结构图的语言。
手势 抽象基类UIGestureRecognier 拖拽手势:UIPanGestureRecognier 关键属性: cancelsTouchesInView 默认为YES。意思是识别到手势发送touchesCancelled事件来终止触摸事件的传递,、
delaysTouchesBegan:默认为NO,意思是在手势识别的过程中,任何一个很小的移动都会被识别为手势。从而发送touchsMoved 消息。设置为YES后,收拾识别是前不会发送touchsmoved消息,会只发送pan事件(手势识别成功)
UITapGestureRecognier 点击手势 UIPinchGestureRecegnier 捏合手势 UISwipeGestureRecognier 滑动手势 UIRotationGestureRecognier 旋转手势 UILongPressGestureRecognier 长按手势
APNS发送系统消息的机制? APNS:是Apple push Notification Service的缩写,是苹果的推送服务器
当用户打开应用程序的通知中心后,苹果远程推送服务器会把消息推送到装有该应用的设备上,具有强制性,实时性的特定
provider:消息提供者,一般是后台服务器或第三方消息推送服务器后台 APNS 苹果的远程推送服务器, ClientApp:客户端app deviceToken:是唯一的由APNS根据设备和app生成的一串数据,但是在重新安装app后会发生改变,或者更新了手机系统也会改变
整体流程是: 1.应用程序App注册消息推送(在正常网络下,ios设备默认会和APNS建立长连接,发生注册事件就会吧ios设备的UDID 和app的bundelid 一起发送给APNS服务器,app只要实现UIApplicationdelelgate中关于远程推送的代理方法,就可以在注册成功的回调中收到通知) 2.APNS将device token 在远程推送注册成功的回调中下发给app。 3.app将devicetoken发送后台服务器provider 消息的提供者 4.应用服务器向APNS服务发送消息 5.APNS服务将消息发送IPHone应用程序
oc与swift区别 gcd与NSOPeration区别 检查内存泄露
内存溢出(out of memory)指程序在申请内存是,没有足够的内存空间可用,就是内存不足的意思。
内存泄露(memory leak) 是程序在申请内存后,无法释放已申请的内存空间,
内存泄露排查方法 1 静态内存分析方法(Analyze):做法xcode-product-Analyze 2 动态内存分析犯法(Instrument的leak) 做法xcode-product-profile-Leaks-choose 点击工具页面左上角的红色按钮开始运行程序 运行结构中红色图标就是出现内存泄露的地方,双击可跳转去修改
内存泄露出现的原因:循环引用 NSTimer delegate block
viewcontroller可定强引用它的子视图。所以子视图对viewcontroller必须是weak 或者assign
_weak __Block
__Block 在arc和mrc下均可以使用,修饰的对象在block中可以被修改,可修饰对象和基本数据类型,本身不会解决循环引用的问题,需要在block内部自动赋值为nil
——weak ARC模式下,用于解决block的循环引用,修饰的对象不能被修改,而且只能修饰对象
ios中事件产生 用户点击屏幕产生触摸事件。系统将事件加入一个有UIApplication管理的事件队列中,UIApplication会从消息队列中取事件分发下去,首先接受到消息的是应用程序的主窗口UIWindow,主窗口会在视图层次中找到一个最合适的视图来处理触摸事件, 找到合适的视图控件后,就会调用视图控件的touch方法来做具体的事件处理 事件传递顺序 UIApplication --》 UIWindow ---》视图层次中最合适处理事件的视图 注意:如果父控件不接受触摸事件,子控件就不可能接收到触摸事件
如何寻找最合适的控件来处理事件
1.通过hitTest:WithEvent判断控件是否接收触摸事件 hitTest:WithEvent 返回nill。表示控件自身及其子空间不是合适的 view。不处理事件 2。通过PointInsid: withEvent判断触摸点是否是控件内 从主窗口UIWindow开始,在子控件数组中从后往前遍历子数组,重复前面的1。2 步骤,找到合适的控件(fitView)(找到fitview后,会便利fitview的子控件,子控件中有合适的view会交给它处理,如果子控件中没有,依然会交给fitview处理处理触摸事件)
UIView 不接收触摸事件的三种情况 1.userInteractionenable = NO 2.alpha <0.01 3.控件自身隐藏。或者控件的父控件隐藏
响应者链条 响应者链条就是事件响应者对象(继承自UIResponder对象)一起组合起来的链条, 是所有可以响应事件的响应者组成的,是从寻找最合适视图的过程中产生的。 事件处理 默认是向上传递事件 如何判断当前响应者的上一个响应者是谁? 1、如果是响应者是控制器UIViewController的View 那控制器UIViewcontrller是它的上一个响应者,否则上一个响应者就是父控件
2.如果传递是视图层次的最顶层依然不能处理事件,则事件传送给UIWindow。UIWindow不处理,会传回给UIApplication ,UIApplication 不处理就会被丢弃
事件传递与事件响应
事件传递是从UIApplicaiton UIWindow UIIVew --fitView 是从父视图到子视图。是寻找最合适view的过程
事件响应是从fitview(最合适视图开始)到UIWidow。 UIApplication的跟过程,。是顺着响应者链条向上传递,是从子视图到父视图的过程
weak属性理解
weak实现原理: runtime 维护了一个weak表,用于储存指向某个对象的所有weak指针。weak表示实际是一个hash表,key是所指对象的地址,value是weak指针地址数组。
1.初始化时runtime调用objc_initWeak 初始化一个新的weak指针指向对象的地址 2.添加引用objc_storeWeak函数调用obc_StoreWeak更新weak指针的指向,创建对应的弱应用表 3.释放,调用clearDeallocating函数,首先根据对象地址(key)获得所有weak指针地址的数组(value),然后遍历数组并将值设为nil,最后将数组从weak表中删除,清理对象的记录。
当weak只用指向的对象被释放时,是如何处理weak指针的? 调用objc_release -》 dealloc --》 objc_RootDealloc ->Objc_destructinstance-->OBJC_clear-deallocating
AFNetworking 底层原理分析
AFHTTPRequstOperationManager。封装了NSUTLConnection 负责网络请求,但已过时
AFHTTPSessionManager 封装了NSURLSession,负责网络请求 AFNetworkReachablityManager 负责网络状态监测 AFSecurityPolity 负责网络安全,针对https请求 AFURLRequestSerialization 序列化工具栏,负责上传数据的json格式化 AFURLReponseSerialization 发序列化 AFJSONReponserSerializer json解析器 AFHTTPReponserSerializer 万能解析器,会自动解析json xml两种数据,其他数据不做任何处理 AFNetworking 封装了NSUTLSession的网络请求,由NSURLSEssion Security reachability, Serialization UIKit 五大部分组成
SDWebImage 原理解说:内存方法相当于一个缓存器,以key value的形式存储图片,当内存不够