总结 总结 总结
命名规范课题
NSString 为什么用copy修饰
Nsstring比较特殊 继承nsobject oc将他归到oc对象。
Oc对象都是动态分配内存 存放到堆区
例如 @“dancer” 只是把数据区的字符串 进行了一个类型转换,oc把他当成字符串对象处理,例如@“dancer”并不是存在堆区,并不是动态分配出来的
我们无法判断这类字符串什么时候释放,如果释放,指针指向他毫无意义
?????
***** objective-c 动态性
编译时/运行时
编译时 词法/语法检查,将代码 编译成计算机执行语言 装到内存中跑起来
运行时
动态类型:
譬如id类型修饰的对象 为动态类型对象 编译时并不知道是什么类型 运行时才会检查确定出对象的类型
iOS 自省方法
is Kindleofclass 检查运行时对象类型
is Memberofclass
动态绑定
基于动态类型 当运行时对象的类型被确定 类的原有的属性 方法被确定,也包括运行时添加的方法 属性,这就是所谓的动态绑定了
核心就是运行时 动态添加属性,方法
动态加载
1 动态资源加载 例如1x 2x 3x 图片 ,程序会根据机型动态加载 不同分辨率的图片
2 可执行代码的动态加载,譬如懒加载
譬如懒加载数组
-(NSArray *)countArray
{
If(!_countArray){
_countArray = [[NSArray alloc] init];
}
Return _countArray;
}
[self.countArray addObject:@“”];
***** 关于kvo:
1 监听机制,基于NSObject 两个方法willChangeValueForKey 和didChangeValueForKey,实现的。
2 当给一个属性添加观察者时候,运行时,会创建一个继承对象所属类的派生类(子类),并且重写被观察属性的set方法,默认一个对象的isa指针会之前所属类,而这是isa会指向这个新的派生类,所以其实被观察的属性的赋值操作是在这个派生类 里实现的。
3 的当被监听的属性发生改变前,调用willChange方法 记录旧的值,改变结束 调用DidChangeValue新的值,出发kvo监听方法。
Ps 对象isa指针默认所属类 class类里面也有个isa指针 指向元类 元类里包含调用的 1 方法列表 2类的版本信息 3成员变量数组ivars等
*****kvo应用场景
1 推送消息 消息时 放数组里面 我们的birgeValue显示红点提示 需要兼监听数组改变 给提示
2 视频 监听进度条
3 做轮播图监听 scrollview 监听contentOffSet
***** 深拷贝 浅拷贝
1 最大的区别就是 有否创建新对象。深拷贝内容拷贝,浅拷贝指针拷贝(内存地址拷贝)
2 深拷贝,修改一个对象不影响另一个对象。
3 浅拷贝,修改一个对象影响另外一个对象
简单说:
深拷贝:指针指向一块新创建的内存
浅拷贝:指针指向一块已经存在的内存
大体上 copy mutable copy 策略是深拷贝
retain strong是浅拷贝
***** Super /self 总结
***** SDWebImage细节
1 sd_setImageWithURL
2 SDWebImageManager 单例 downloadImageWithURL
内部 SDImageCache类(nscache)以以url为key queryDiskCacheForKey方法 Memory Cache 以url为key去内存中查询缓存图片,如果没有 Disk Cache:去磁盘上找。
如果磁盘找到,会将图片设置到memory cache中。
3 如果缓存数据查询成功,则返回,不成功则请求网络self.imageDownloader down…
4 如果下载成功 [self.imageCache storeImage]储存 completedBlock回调前端展示
ps 磁盘缓存清除策略
1 清理过期缓存
2 清理写入时间早的图片
@interface SDImageCache : NSObject
@property (assign, nonatomic) NSInteger maxCacheAge;//最大缓存时间
@property (assign, nonatomic) NSUInteger maxCacheSize;//最大缓存空间
//设置最大缓存空间
[SDImageCache sharedImageCache].maxCacheSize = 1024 * 1024 * 50; // 50M
SDWebImage Bug
磁盘图片渲染之前,需要得到图片的原始像素数据,然后去做绘制操作,所以图片需要解压缩。
***** 公司刷新 流程
size :取多少
offset:从哪里取
count:总数
刷新:
设定size 20条 10条,offset 为0 加到数组中
加载:
设定size20条 10条,第一次 获取数据数组长度 offset 从这取值 取size条,加到数组。
判断更多 has 数据数组个数< count总数
设置footer view 给个提示 没有更多
***** SVPullrefresh 原理
创建个scrollView的分类 分类添加属性,刷新头部显示的view 高度60 ,添加头部刷新view为scrollview的观察者,监听contentOffSet的改变,刷新头部view 有几种状态,加载状态,初始状态,停止状态,拖拽状态,在观察者监听方法里面,根据几种状态切换执行layoutSubview的显示
*****bug
Bug复现:当下拉刷新 拽的不是太多时候,他会先调上拉加载,在下拉刷新。
原因:1 svpull的头部/尾部试图都是scrollview的观察者,监听contentOffSet,2 当拖拽时候结束,scrollview代理结束 两个都调用,设置刷新状态,操作ui。
方案:加判断,scrollviewdidScroll 拖拽结束,判断当前偏移量 如果y>0 做上拉加载时候,设置加载状态 loding状态
uiscrollview的分类
/**********************************************************************************/
*****tableview 滑动 cell 崩溃 (会议人气榜)
且仅仅4s崩溃,其他的不崩溃 而且会有内存明显的飙升 正常100左右飙升到800
断点调试 崩溃在sdwebimage里面 沙盒取出的图片转码 转位图时候,正常我们设置图片imageview setimage 都是在主线程中设置的 这其就包括解压图片为位图(很耗cpu) 然后calyer在view上做渲染。sdwebimage做法是开子线程去去做这个位图的解压缩,然后缓存 供ui使用,去沙盒中去图片的时候不做任何处理,直接取,这次奔溃的原因就是后台返回的图片太大 3000*5000,方案有两个第一大图片不处理 不解码这样性能差点 但不崩溃
第二种是 沙盒取出的图片 先等比压缩下。
我的方案是综合下 沙盒取出图片先判断如果款大于屏幕宽度 等比压缩下,小的不压缩,然后再去转码
******* 线程同步
防止资源抢夺,让线程同步进行,可以加互斥锁/NSLock,
@synchronized(obj):针对对象 ,保证在多条线程同时操作obj时候,一条线程执行完,在执行另一个
NSLock:针对方法,给一条线程中操作对象的方法加锁,保证一条线程执行完,在执行另一个
场景:三方库
******* 多线程场景应用
qq分享要求的图片1m以内,后台传的图片1.2m发布出去 回调不掉。
方案:下载图片nsdata datawithurl 网速慢直接卡死 要开线程 图片存储沙盒,等比压缩图片
******* 信号量 GCD实现 设置线程并发数 / 设置线程顺序
信号量:资源计数器
信号量介绍:
资源计数器,对于信号量有两个操作达到互斥 v(发送信号)/p(信号等待)
当一个操作执行A 执行p操作,信号量为-1未零,系统规定信号量为0,等待,操作A执行完毕,执行v操作,信号量+1,释放资源,线程B才可以执行.通过信号量来达到互斥操作.
方法介绍:
1 创建信号量 指定资源数量
2两个重要参数 发送信号(V),等待信号(P)
part 1 设置线程顺序 (通过一个执行,其他阻塞的方式实现顺序)
1 设置信号量为1,开启一条线程操作时候信号量-1,当前程序信号量为0,则其他线程操作阻塞状态,当当前线程执行结束,信号量+1,则其他线程操作 恢复执行.
2 通过开启一条线程,来阻塞其他线程,来实现多线程执行顺序.
part 2 设置线程最大并发数
同样设置信号量 为3,来实现最大线程并发数为3的功能
1 信号量为三,意味着可以开启三条线程操作.
2 同样通过开启一条线程 信号量-1 线程指向完毕 信号量+1,实现程序运行中,有三条线程可以执行多线程操作,从而实现最大线程并发数.
******* xmpp 环境配置
材料:openfire服务器 mysql数据库(默认装到控制面板)
1 openfire mac版 基于java开发的 所以要求电脑有java运行环境
没有的话需要安装jdk 查看java运行环境 终端执行命令 运行java -version
2 mysql (服务端的数据库)使用是需要有账户密码默认装到控制面板)
1》安装完 mysql 默认账户是root 密码为空
2》终端命令配置命令行配置 开启mysql 并设置密码
3》创建的数据库默认四个文件 有个test文件
4》管理工具navcat 还有个海豚(mysqlworkbeech)的 登录输入连接名称(自定义)输入IP地址 端口号默认3306
账户名称 root 密码(你配置过得)配置的数据库名称为你自定义的名称
3 关联openfire 和数据库1 导入openfire数据表文件到mysel(创建字段包括用户等)
1》openfire建立数据库文件openfire数据库编码选择utf-8的
2》默认open fire数据库安装到/user/local/openfire/ 数据库脚本保存在/user/local/openfire/ /resources/database/中
支持很多种数据库 保存mysql的数据库到桌面 导入到mysql中,这样mysql就添加好数据库字段了
4 关联openfire 和数据库1 后台管理设置关联数据库mysql
后台配置 选中驱动类型:mysql 指定mysql路径 输入mysql 用户名密码:root 密码:123456
配置openfire 后台账户密码 admin 123456
设置jid:
***** const / #define 宏定义
const c/c++ 定义常量的关键字
#define 预编译指令
>>相同点
都能定义常量
>>不同点
1 从内存分配角度,
const 编译器不会为他分配内存空间,而是存储在符号表中,,作为一个常量存在,在编译时不会有存储/读取内存的操作
#define 编译时候,,每次赋值操作,先进行宏替换,然后都开启新的内存
所以 在运行时 const只被拷贝一份,而 #define 可以有若干个拷贝 const效率会高于#define
2 从使用角度
#define 可以定义函数,可以定义单例,而const不可以
备注: 苹果推荐使用const 因为const是在编译阶段,会编译检查报错;而宏定义,在预编译阶段 仅仅是替换 编译阶段 不检查类型
From http://www.cocoachina.com/ios/20160519/16342.html
***** static / extern 全局变量 局部变量牛逼闪闪
static:修饰变量(全局,局部)使用 / 全局变量/static变量 存储在静态区 程序运行 只初始化一次
两个作用
Part1 :局部变量copy 进静态区,延长局部变量声明周期,程序运行期间 一直存在
Part2: 防止全局变量外部引用,外部引用extern
》》修饰局部变量:
作用:延长局部变量生命周期 (类似给局部变量变为全局变量的意思!)
ps:局部变量本身存储堆栈区,方法结束局部变量随之销毁;static修饰后将局部变量copy到静态区,修饰后变量在运行中在静态区给局部变量分配一次内存空间,且仅仅执行一次,程序运行期间变量一直存在不会销毁。
ps:打点断 ,发现下次执行这里断点过到下面去了。
》》修饰全局变量:
主要是作用域的问题,static修饰后仅在本类中可以使用,无法extain引用,全局变量则可以外部引用。
场景:int做自增运算
extern:外部引用 UIKIT EXTERN(牛逼闪闪的宏定义 吼吼~~)
一个类中声明(即使写在方法里面也无妨),另一个类extern 可以直接引用。
备注:1 其他类声明NSString *abcdefg = @“红咔嚓雷“,
2 当两个类同时声明NSString *abcdefg 则编译报错,两个文件同事O文件报错 解决:
ps:无需等到程序会否执行到该方法,程序启动即分配内存空间,所以无需加载到该方法。
ps:个人理解,类似通过extern关键字从静态区 引出一个全局变量的意思,然后重新声明,使用。。。
全局变量:变量存储在静态区,程序运行时分配一次内存空间,然后不会再去执行了。
局部变量:存放在栈空间中,方法执行结束,变量销毁。
????为什么 类方法 要用static 修饰全局变量
***** 堆栈
栈 编译器管理内存 栈的容量是系统预先设定好的 超了就会overflow ,分为动态分配/静态分配,局部变量 静态分配;静态/动态分配 都是由编译器管理内存的
堆:程序员手动管理内存 堆都是动态分配内存的
***** @autoreleasepool
@autoreleasepool :作用避免内存峰值
数据比较
加上 @autoreleasepool 内存恒定在27
不加上 @autoreleasepool 内存27起 匀速飙升 结束53
Ps:在自动释放池中 调用autorelease方法才会被放到自动释放池,方法结束,才会对对象发送releas方法
结论:当出现大的for循环 且循环体内api为 @autorelease时候建议加autoreleasepoor
且:autoreleasepool 不能优化所有的循环
******************* ******************* ******************* ******************* ******************* *******************
引申:@autoreleasepool应用场景
1> 大数字for循环时候,调用autorelease API方法时候,加入@autoreleasepool{}避免内存峰值
例如:拼接字符串操作,stringWithFormat API创建字符串,临时变量被大量创建,持续开辟内存,内存持续飙升....for循环结束,对象才会销毁,此时加入@autoreleasepool 会有帮助
如果字符串是alloc 出来的,非autorelease API 则 @autoreleasepool 是无效的
***** 项目性能优化
1 懒加载 场景:初始化UI控件 2NSDateFormatter(日期格式化)
2 tableview优化 实现: 高度,数据 提前缓存,tableview只做赋值运算 减少subVies数量,rowHeight sectionHooterHeight 直接设定,少用代理
3 常识注意
***** NSURLCache
缓存原理 NSURLQequest 对应一个NSURLURLCacheResponse
缓存NSURLCache *cache = [NSURLCache shareURLCache];//掌握全局缓存
***** Block常识
***** Block常识 (一)
方法常用声明:@property (copy) void(^MyBlock)(void); 如果超出当前作用域之后仍然继续使用block,那么最好使用copy关键字,拷贝到堆区,防止栈区变量销毁
定义block
typedef NSString (^WebBaseHandlerBlock) (NSDictionary *retInfo, NSError *error);
属性block
@property (nonatomic ,copy)abcBlock myblock;
@property (nonatomic ,copy)void (^youBlock)(NSString *);
_weak typeof(self) weakSelf = self;
因此,__block和__weak修饰符的区别其实是挺明显的:
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block对象可以在block中被重新赋值,__weak不可以。
PS:__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。
***** Block和copy (二)
为什么要用copy:出于作用域考虑,默认block 存放在栈中,函数调用,栈分配内存,函数结束释放内存,block 销毁。再次调用block 时候报错野指针错误。当前block 变量指向的被释放的内存地址。所以需要copy到堆中,包住block的命。
“他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。”
***** Block copy/strong (三)
使用retain也可以,但是block的retain行为默认是用copy的行为实现的,
因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
***** Block copy/strong 扩展
block几种类型NSGlobalBlock NSStackBlock
block内部不引入外部变量:__ NSGlobalBlock
block内部引入外部变量 :__ NSStackBlock
***** weak 实现原理
runtime维护这个一个weak表(哈希表),记录已对象的地址为key,value为 所有指向该对象的weak弱指针地址的数组,当对象销毁时候通过weak表中该对象地址的value,查找到存有所有弱指针的地址的数组,赋值为nil,然后从weak表中删除。
对象销毁 会调用objec_clear_deallocating函数
PS:怎么找 对象地址 对应所有指向给对象的weak指针数组
block 使用
===场景1
譬如 协议中封装一个 push控制器的操作
调用方:
[**** **block^(id obj ,NSInteger type){
if(type ==1){
[self.navagation pushViewController:obj animation:YES];
}
}];=
+(void)**. ** :(**block)block
{
Uiviewcontroller *obj = [[UIViewController alloc] init];
if(block){
block(obj,1);
}
}
===场景2
譬如 封装一个 请求url block操作
调用方
[webbasehander geturl:@“” dict:dic block^(id result ,NSError error)
操作result
[self.table reloadData];
];
- (Void)getUrl:(nssting *)url dict:(nsdictionary *)dict block:(**block)block
{
配置url
配置请求参数
[self request:url:block];
}
- (void)equest:(nesting *)url block:(**block)block
{
ASI 请求
Request completionBlock{
block(dic,error);
}};
}
总结 :当 封装方面 设置好数据 触发调用方的block,调用方获取到值 ,操作后续部分
assign weak 区别
assign:修饰对象,和基本数据类型;当被修饰的变量指向变量释放或置空,会出现野指针错误!
weak:只能修饰对象,不会出现野指针错误,当被修饰的变量指向的变量释放或是置空,被修饰变量指向nil,不会出现野指针错误。
引申
***** 内存分析
静态内存分析 analyze、分析/ 蓝色
例如:逻辑错误
logic error / Dead store/Memory
不是太准 不可变赋值给可变数组 ,调方法时候传入的字典参数未实例化
动态内存分析 profile -allocation /leaks 侧面/分配/泄漏
***** IOS 绘图
Ios图像绘制三种API
1 UIKIT
UIBezierPath (画线,椭圆 角度 照相机) UIImage 显示图像
2 CoreGraphics/ Quartz 2D (c语言函数API)
Quartz 2D 是2d绘制呈现引擎
CoreGraphics CGContent CGPath CGLayer CGBitmap
3 Open GL
支持2d/3d
CoreAnimation 算动画引擎
*****手势 响应者链条
分两块,
1 定位接收者
2 响应者链条
1定位接收者 当点击屏幕的ui触发一个事件,流程是事件添加到UIAplication的事件组,传递事件经历 window ,父控件且判断控件是否接受事件,如果是,则父控件遍历子控件,判断当前出发点是否在子控件上,继续遍历直到找到触发该点的最后一个子控件,事件传递不可以断,以为这所有控件务必可以处理事件,获取执行触发事件的控件。
ps:这就说明了 为什么交互期间中间有个什么uiimageview等不能交互的父控件,导致子控件不接受响应事件
可以接受响应事件的控件需要继承UIResponder 但还不够 需要可以交互 不是隐藏的 alpha值不是太小
2 响应者链条,功能是一个事件的发生,可以被多个控件获取。回传靠的是super执行方法
举例子:view上事件触发 默认事件互传给父控件,继续回传父控件,控制器.view 控制器(一样继承uiresponder);如果控制器还有父控制器那就父控件传递 给控制器 然后self.view 然后父控制器 window uiapplication
*****runloop
五中模式
1 UITrackingRunLoopMode
2 NSDefaultRunLoopMode
3 内核
4 开始
5NSRunLoopCommonModes = UITrackingRunLoopMode + NSDefaultRunLoopMode
获取两种方式 mainRunLoop currentRunloop
nstimer 会用到
平时api [NSTimer schedulerTimerWithTimeInterval:1.0 targer:self selected:@selected(timerMethod)userInfo:nil repeats:YES]; // NSDefaultRunLoopMode 默认用的这个 所以处理滑动ui时候 timer 挂起 不执行了
repeats:YES
所以还是 需要实例化
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 @selected(timerMethod)userInfo:nil repeats:YES ];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:runLoop withMode:NSRunLoopCommonModes];
*****CALayer 详解 CALayer /UIView
CALayer : 负责绘图 属于quartzCore框架,是一套跨平台绘图框架(Mac osx,ios)所以 layer.backgroundColor是CGColorRef,(因为Mac osx 没有UIKit,osx不是触摸交互的)
UIView : 继承UIResponder 可以做交互,属于UIKit框架 负责构建用户界面和管理内容.
关 系 : 简单的说就是 UIView内部封装了一个CALayer的对象,calayer对象负责绘图部分,UIView负责交互和管理内容.
当对UiView进行绘制操作属性时候,例如frame center backgroundColor,实际会调用对应layer的相关方法
例如调用 view setframe 实际会调用layer的 positon bounse anchorPoint
备注:
CALayer 属性 position anchorPoint(锚点) bounse size transform等
UIView的frame实际上是由center 和bounds来决定的
UIkit 构建界面,相应事件
锚点与中心点重合,默认0.5-0.5,
Layer内含隐士动
https://blog.csdn.net/u013282174/article/details/50215605
*****TCP UDP 协议——
TCP (传输控制协议):
1 建立连接,形成数据通道
2 传输数据大小不受限制
3 三次握手,建立长连接,安全协议
4 必须建立连接,效率稍低
UDP(数据报协议):
1 无需建立连接,将数据源及目的封装成数据包
2 传输大小有限制 小鱼64kb
3 无需建立连接,非安全协议
4 速度快
*****get post tcp udp 传输协议等 ???
*****注册登录 加密流程 对称非对称加密 ????—
*****你在公司负责什么——
*****上传app 推送 ——
*****数据库 sqlite语句——
*****公司缓存策略 首页等——
*****多线程应用 线程同步等 什么线程池
*****runtime 应用场景 事例介绍 ——
场景1
控制器释放打印( 添加属性 关联)
奇葩:logDealloc对象 管理打印信息
原理:
1 push每次新建控制器,initXib调用分类方法 创建一个logDealloc对象 用个属性记录当前类名
2 防止方法结束对象释放,在分类中需要,用个全局变量保存该对象(属性为类名),因为是分类所以关联创建属性,
3 pop控制器(本类)销毁,分类销毁,logDealloc对象销毁,调用对象logDealloc的dealloc方法 打印类名
场景2
控ios默认字体Heiti SC
*****web跳转———
*****单例模式—
*****镂空的遮罩
nsmarch port???
0 思路:蒙版.layer.mask = layer对象
1 创建蒙版
2 绘制贝塞尔路径 添加反转图形(叠加部分会镂空)
3 创建layer(CAShapeLayer子类).path = 贝塞尔路径.path
4 设置 蒙版.layer“.mask = layer对象
创建表
create table if not exist t_student (primary key autoincrement,id integer ,name text not null,age integer default 18,)
创建表 create table if not exist 表名(字段 类型 约束,字段类型 约束,…)
增
insert into t_student (id,name,age) values (001,“小明”,20);
删除
delete from t_student where age>20 and name “小明”;
改
update
公司缓存机制
#define HUIYIONELEVELCACHES [YYUtil CreatCacheschilderPath:@"HUIYIONELEVELCACHES"]//会议页面研究报告1级分类缓存
/var/mobile/Containers/Data/Application/6AB6ABF0-29D8-415C-A71A-239D802FF9D0/Library/Caches/AppCaches/HUIYIONELEVELCACHES
心得体会
上线 要注意是否有 版本升级问题
播放url 视频注意转码 防止地址中带中文
[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMachPort ???
递归锁
runloop
内存管理
哈希表
二叉树
自动释放吃
推送
本地推送:
http://www.cnblogs.com/ly1973/p/8848459.html
远程推送
http://www.cnblogs.com/ly1973/p/8848404.html
分享
三方登录
推送
Im即时通讯
视频开发
内存泄露
性能优化
缓存
音乐播放
数据统计
数据库加密
打包上线
多线程
决定是否开辟线程 看同步/异步 不是看队列