<center>整理
MRC和ARC区别
- MRC: (Manual Reference Counting)也就是非ARC,在Xcode4之前,Object_C的内存管理就需要开发人员手动维护。
- ARC: (Automatic Reference Counting)也就是ARC,翻译成中文就是:【自动引用计数】,不需要开发人员手动维护,系统会在合适的时候调用内存管理方法。
内存区
五大内存区域分别为
- 栈区:创建临时变量时由编译器自动分配,在不需要时自动清除的<font color="red">变量的存储区</font>。里面的变量通常为<font color="red">局部变量</font>、<font color="red">函数的参数</font>等。
- 堆区:就是那些有new alloc创建的对象所分配的内存块,它们的释放系统不会主动去管,由开发者去告诉系统什么时候去释放。
- 全局区:<font color="red">全局变量</font>和<font color="red">静态变量</font>被分配到同一块内存中。
- 常量区:存放常量的区域,不允许修改。
- 代码区: 存放函数的二进制代码区域。
- 自由存储区(五大区域之外区):由malloc等分配的内存块,它们有free在释放
说说地图的使用
- 首先要在info.plist文件中添加配置
- NSLocationAlwaysUsageDescription
- NSLocationWhenInUseUsageDescription
- 地图坐标系
- 百度地图
说说hybird应用的技术 ???
TableView的使用 tableViewcell基类的设计
-
重用机制的正确使用
-
对于复杂的cell 尽量使用纯代码布局 因为 xib、storyBoard 需要系统自动转码
-
缓存高度 (如果计算复杂 子线程去计算)
-
异步加载图片 SDWebimage 已实现
-
减少使用透明视图
-
减少subviews的数量和层级数
-
不要动态的在cell上添加view 可以在初始化的时候添加 然后控制显示 隐藏
-
避免subview的层级调整
-
圆角优化
- cell中出现的圆角还是比较常见的 通常我们处理圆角都会使用
imageView.layer.cornerRadius = 10; imageView.layer.maskToBounds = YES
这样处理就会造成离屏渲染 性能损耗
-
使用贝塞尔曲线UIBezierPath和Core Graphics框架画出一个圆角。
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; imageView.image = [UIImage imageNamed:@"myImg"]; //开始对imageView进行画图 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); //使用贝塞尔曲线画出一个圆形图 [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip]; [imageView drawRect:imageView.bounds]; imageView.image = UIGraphicsGetImageFromCurrentImageContext(); //结束画图 UIGraphicsEndImageContext(); [self.view addSubview:imageView];
-
使用CAShapeLayer和UIBezierPath设置圆角(比较处理方式1更优)
UIImageView*imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100,100,100)]; imageView.image = [UIImage imageNamed:@"myImg"]; UIBezierPath*maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:imageView.bounds.size]; CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; //设置大小 maskLayer.frame = imageView.bounds; //设置图形样子 maskLayer.path = maskPath.CGPath; imageView.layer.mask = maskLayer; [self.view addSubview:imageView];
- CAShapeLayer
- CAShapeLayer继承于CALayer,可以使用CALayer的所有属性值.
- CAShapeLayer需要贝塞尔曲线配合使用才有效果
- CAShapeLayer动画渲染直接提交到手机的GPU当中,相较于view的drawRect方法使用CPU渲染而言,其效率极高,能大大优化内存使用情况。
- 总而言之,CAShapeLayer的内存消耗少,渲染速度快。因此处理方式2较处理方式1更优。
- CAShapeLayer
-
使用一个透明底圆形的同颜色的边的图直接盖上 直接避免了离屏渲染
-
直接使用切过圆角的图
KVC和KVO的原理 [详解点击](url https://blog.csdn.net/bolted_snail/article/details/82147675)
- KVC: <font color="red">KeyValueCoding</font> 俗称“键值编码”, 是一个基于NSKeyValueCoding非正式协议的机制,就是直接通过key值对对象的属性进行存取操作,而不是通过明确的存取方法。
<font color="red">注:NSObject是定义了KVC的,所以继承NSObject的对象都支持KVC,基本上所有的OC对象都支持KVC。</font>
- setValue:forKey:
- setKey:
- _setKey:
- 查看+ (BOOL)accessInstanceVariablesDirectly; 是否返回YES(默认YES),如果是YES继续执行,如果是NO抛出异常NSUnknownException。
- _key
- _isKey
- key
- isKey
- NSUnknownException
- valueForKey:
- getKey
- key
- isKey
- _key
- 查看+ (BOOL)accessInstanceVariablesDirectly; 是否返回YES(默认YES),如果是YES继续执行,如果是NO抛出异常NSUnknownException。
- _key
- _isKey
- key
- isKey
- NSUnknownException
- KVO <font color="red">KeyValueObserving</font> 俗称“键值监听”,可以用于监听某个对象的属性值的改变。 KVO是通过isa-swizzling技术实现的(这句话是整个KVO实现的重点)。在运行时根据原类创建一个中间类,这个中间类是原类的子类,并动态修改当前对象的isa指向中间类。并且将class方法重写,返回原类的Class。所以苹果建议在开发中不应该依赖isa指针,而是通过class实例方法来获取对象类型。
自动释放池 AutoreleasePool
-
AutoreleasePool是OC中一种内存自动回收机制,它可以延时加入AutoreleasePool中的变量release的时机,在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入到AutoreleasePool,那么release将延时执行。
-
AutoreleasePool是以栈为节点,通过双向链表的形式组合而成,AutoreleasePool是与线程一一对应的。
- 双向链表的单位是节点,从头结点开始一直到尾结点,每一个节点都会有一个父指针和子指针,父指针指向前一个的节点,子指针指向后一个节点,而头节点的父指针指向NULL,尾节点的子指针指向NULL。这样就把栈空间通过双向链表的形式连接起来了。
-
在AutoreleasePool中有四个变量分别为:
id *next AutoreleasePoolPage *const parent AutoreleasePoolPage *child pthread_t const thread
- id *next 一个id类型的指针,指向的是下一个可存储对象的位置。
- AutoreleasePoolPage *const parent 这个就是当前page父节点page的地址指针。
- AutoreleasePoolPage *child 子节点的地址指针。
- pthread_t const thread 这个变量中记录了线程的情况,所以说自动释放池是与线程一一对应的关系。
代理和Block
- NotificationCenter 通知中心:一对多,在app中如果很多控制器需要知道同一件事情,应该使用通知
- delegate 代理委托:一对一 对同一个协议,一个对象只能设置一个代理,所以单利对象就不能使用代理 代理更注重过程
- block 闭包:一对一 相对于delegate block有以下特点
- 写法更简单
- block注重结果的传输
- block需要注意防止循环引用
单利为什么不使用代理
单例只有一个对象且存在APP的整个生命周期,1、如果你先设置为A的代理,然后设置成B的代理,A的代理就会失效;2、代理一般是weak修饰为的就是不再使用的时候自动释放,而单例你是释放不了的,这样就会存在内存泄漏 3、因为它一直存活还是某个对象的代理就可能引发很难查找的问题
load与initialize
load
- 编译器自动调用 每个类都会调用 并且在main函数之前调用
- 每个类的调用顺序跟项目加载的顺序有关 项目 -> TARGETS -> Build Phases -> Compile Sources 从上往下调用
- 继承关系并且父类实现的分类 父类 -> 子类 -> 分类
initialize
- 类初始化时调用 无论初始化多少次只会在第一次初始化时调用
- 如果类有分类那么分类的initialize方法会把类本身分initialize方法替换掉
- 继承关系 父类 -> 子类
block
block原理,本质
- NSGlobalBlock (_NSConcreteGlobalBlock) 数据区
- NSStackBlock (_NSConcreteStackBlock) 栈区
-
NSMallocBlock (_NSConcreMallocBlock) 堆区
继承自NSBlock -> NSObject
...
__block的作用,有什么使用注意点
__block本身无法避免循环引用 但是我们可以在block内部手动把blockObj赋值为nil的方式在避免循环引用
__block修饰的变量在block内外都是唯一的
__weak本身可以避免循环引用,但是会导致外部对象释放后,block内部也访问不到这个对象。我们可以通过在block内部声明一个__strong的变量在指向weakObj,使外部对象既能在block内部保持住,又能避免循环引用的问题。
block的属性修饰为什么用copy,使用block需要注意什么
block一旦没有进行copy操作 就不会在堆上
block在堆上 程序员就可以对block做内存管理等操作,可以控制block的生命周期
block在修改NSMutableArray 需不需要添加__block
不需要
delegate用 weak 和 assign 修饰的区别
- strong:该对象强引用delegate,外界不能销毁delegate对象,会导致循环引用
- assign:也有weak的功效,不会产生循环引用。但是assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能会出现野指针
- weak:指明该对象并不负责保持delegate对象
事件传递和响应者链
只有继承了UIResponder的类才能处理响应事件
CALayer继承自NSObject 无法处理响应事件
事件传递:UIApplication -> UIWindow -> UIView
响应者链:UIView -> UIViewController -> UIWindow -> UIApplication
扩大点击范围
// 此方法返回的View是本次点击事件需要的最佳View
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
// 判断一个点是否落在范围内
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
// 扩大按钮的点击范围
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
CGRect bounds = self.bounds;
bounds = CGRectInset(bounds, -10, -10);
// CGRectContainsPoint 判断点是否在矩形内
return CGRectContainsPoint(bounds, point);
}
Runtime
Runtime介绍
..................
KVO && KVC
[self class] [super class]
atomic
autoreleasepool
autoreleasePool是由多个autoreleasePoolPage组成的一个双向链表
autoreleasepoolpush -> 静态的 push -> autoreleasepoolfast
hotpage() 有page并且page没满 (4096字节)就执行add 如果page满了 就执行autoreleasepagefullpage 如果没有page就执行 AutoreleaseNopage
autoreleasepagefullpage方法 从传入的pa个开遍历整个双向链表 直到 找到一个未满的page或者 创建一个的新的page 上一个的page的child指向新的创建的page 新创建的page的parent指向上一个page 然后将新找到或者创建的page设置成hotpage 在执行add方法
AutoreleaseNopage方法 创建见一个新的Autoreleasepoolpage (新创建的没有parent指针)
并把新的Autoreleasepoolpage设置为hotpage 然后add一个哨兵对象来确保pop是不会异常 最后add(obj)
Autoreleasepoolpop -> 静态的pop 从最下方调用pop 依次释放栈中的对象 直到遇到标识符
事件传递和响应机制
runloop
weak
weak 是runtime维护了就是一个哈希表 key是指向对象的地址 value是weak指针的地址数组
当dealloc调用时 runtime会以obj为key找到对应的value 依次释放
http 和 https
TCP/IP 四层模型
- 应用层 : FTP 、HTTP、DNS、SMTP
- 运输层 :TCP、UDP
- 网络层 : IP
- 链路层 :硬件接口
OSI参考模型
- 应用层:应用层协议, HTTP、FTP、SMTP
- 表示层 :加密解密、压缩解压
- 会话层 : 不同机器上用户之间及管理会话
- 传输层 : 接受上一层数据, 必要的时候把数据进行分割, 交给网络层, 保证数据段有效到达对端
- 网络层 : 控制子网的运行、逻辑地址、分组传输、路由选择
- 数据链路层:物理寻址
- 物理层:原始比特流传输
HTTP
超文本传输协议, 默认端口是 80
特点
- 无状态: 每次请求都是独立的, 两个请求之间没有联系, 但是会引入 Cookie 和 Session 机制来关联请求
- 无连接:服务端收到客户端请求后, 响应完成并收到客户端的应答之后, 立即断开连接
请求报文
- 请求行
- 方法 : GET 、POST 、HEAD、PUT、DELETE、OPTIONS
- URL 字段
- HTTP协议版本号
- 请求头
- Accept: 浏览器可以接受的 MIME 类型
- Accept-Encoding:浏览器支持的编码类型
- Accept-Language: 浏览器支持的语言
- Content-Length : 请求消息的正文长度
- Content-Type : 客户端接受服务器返回的文件类型
- User-Agent : 请求的用户信息, 浏览器类型
- Host : 给出接受请求的服务器主机名和端口号
响应报文
- 响应行
- 报文协议及版本
- 状态码及描述
- 响应头
- Content-Length : 响应消息长度
- Content-Type : 当前内容的 MIME 类型
- Server : 服务器名称
- Set-Cookie : 设置 cookie
- 响应码
- 1xx : 临时响应, 需要请求者继续执行操作
- 2xx: 成功处理了请求的状态码
- 3xx : 如果要完成请求, 需要进一步操作, 重定向
- 4xx : 请求出错
- 5xx: 服务器内部错误
HTTPS
默认端口号是 443
- 客户端请求 https 连接, 服务器收到请求后会把证书信息(包含公钥和签名) 返回给客户端
- 客户端会校验这个证书签名的有效性从而获取到公钥
- 客户端随机生成会话密钥(对称加密), 然后利用证书里面的公钥将会话密钥加密, 连同加密后的内容传送给服务端
- 服务器利用私钥解密出会话密钥, 然后解密出内容
- 服务端利用会话密钥通信
HTTPS 优缺点
优点
- 可以认证用户和服务器, 确保数据发送到正确的客户端和服务端
- 防止数据在传输过程中不被窃取、改变, 确保数据的完整性
缺点
- 比较耗时, 页面的加载时间延长 50%, 增加 10% 和 20%的耗电
- SSL 证书要钱
- https 连接缓存不如 http 高效
- 并非绝对安全, 掌握CA证书机构、加密算法的组织任然可以进行中间人形式的攻击
http 和 https 的区别
- http 协议没有加密, https 对传输数据加密, 保证用户信息
- http 默认端口是80, https 默认端口是443
- http 无需证书, 而 https 需要购买证书
http 1.x 和 http 2.0 的区别
- 新的二进制格式: 1.x 的解析是基于文本的, 2.0是二进制格式
- 多路复用: 连接共享。 1.x 每次请求都建立一个链接, 用完关闭, 串行单线程处理, 后面的请求等待前面请求返回才能执行。 2.x 多个请求同时在一个连接上并行执行
- header压缩: 1.x 的header 有大量信息每次都要重复发送, 2.0 使用 encoder 来减少传输的 header 大小
- 服务端推送
get 和 post 的区别
- get 的请求放在 URL 上, 参数之间以 & 相连, post 请求放在 http body 内
- get 的提交数据最大有限制, 跟环境有关系, post 理论上没有限制, 大小由服务器设定
- get 产生一个 TCP 数据包, 浏览器会一起发送 header 和 data, 服务器返回200 post 有些服务器是只发一个 TCP 数据包, 有些会先发送header, 服务器返回100后, 再发送data, 返回200
- get 请求会主动 cache, post 不会, 除非手动设置
- get 在浏览器返回时是无害的, post 会再次提交请求
网友评论