iOS每日一记之———————————————重点难点总结.....orz

来源:互联网 发布:氪星网络 编辑:程序博客网 时间:2024/06/05 01:18
socket套接字的格式 socket半包 粘包 怎么修改
socket套接字的格式
  1. int socket (int domain, int type, int protocol); //成功:返回套接字描述符;失败:-1 
  2. 套接字的特性有三个属性域(domain),类型(type),和协议(protocol)。套接字还用地址作为它的名字。地址的格式随(又被称为协议族,protocol family)的不同而不同。每个协议族又可以使用一个或多个地址族定义地址格式。

socket半包 粘包 是什么 以及怎么解决

粘包:粘包就是多组数据被一并接收了,粘在了一起,无法做划分

半包:半包就是有数据接收不完整,无法处理

解决方法:一般在设计数据(消息)格式时会约定好一个字段专门用于描述数据包的长度,这样就使数据有了边界,依靠这个边界,就能把每组数据划分出来,数据不完整时也能获知数据的缺失。(当然也可以把数据设计成定长数据,但这样不够灵活;或者用\n,\r这类字符作为数据划分依据,但不直观、不明确,同时也不灵活)。
以下是代码解决方法:
  1. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag  
  2. {  
  3.     while (_readBuf.length >= 10)//因为头部固定10个字节,数据长度至少要大于10个字节,我们才能得到完整的消息描述信息  
  4.     {  
  5.         NSData *head = [_readBuf subdataWithRange:NSMakeRange(010)];//取得头部数据  
  6.         NSData *lengthData = [head subdataWithRange:NSMakeRange(64)];//取得长度数据  
  7.         NSInteger length = [[[NSString alloc] initWithData:lengthData encoding:NSUTF8StringEncoding] integerValue];//得出内容长度  
  8.         NSInteger complateDataLength = length + 10;//算出一个包完整的长度(内容长度+头长度)  
  9.         if (_readBuf.length >= complateDataLength)//如果缓存中数据够一个整包的长度  
  10.         {  
  11.             NSData *data = [_readBuf subdataWithRange:NSMakeRange(0, complateDataLength)];//截取一个包的长度(处理粘包)  
  12.             [self handleTcpResponseData:data];//处理包数据  
  13.             //从缓存中截掉处理完的数据,继续循环  
  14.             _readBuf = [NSMutableData dataWithData:[_readBuf subdataWithRange:NSMakeRange(complateDataLength, _readBuf.length - complateDataLength)]];  
  15.         }  
  16.         else//如果缓存中的数据长度不够一个包的长度,则包不完整(处理半包,继续读取)  
  17.         {  
  18.             [_socket readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据  
  19.             return;  
  20.         }  
  21.     }  
  22.     //缓存中数据都处理完了,继续读取新数据  
  23.     [_socket readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据  

如何加载高清大图  大小为5000X5000的
 
加载高清大图内存暴涨 是因为大图是高清的 分辨率很高 解压缩过程中造成的。解压缩操作中,每一个像素点都会分配一个空间来存储相关值,那么分辨率越高的图片,就意味着更多数量的像素点,也就意味着需要分配更多的空间!所以对于高分辨率图来说,解压缩操作的确会造成内存飙升,即使是几M的图片,解压缩过程中也是有可能消耗上G的内存!
解决思路如下:直接让下载高分辨率图的地方,禁止解压缩操作。高清图涉及到的地方,都全部已经封装起来了,那么就轻松了很多。为了保证封装类不对外界产生影响,我只在调用封装类时,禁用解压缩,调用完毕再恢复原设置即可。这样既能保证高分辨率图不crash,也能保证其他地方,普通图片依旧可以通过解压缩进行优化。
代码思路如下:1、首先在封装的控制器中定义变量用于存储原设置:
static BOOL SDImageCacheOldShouldDecompressImages = YES;static BOOL SDImagedownloderOldShouldDecompres

2、loadView中保存原设置并且禁用解压缩:

SDImageCache *canche = [SDImageCache sharedImageCache];SDImageCacheOldShouldDecompressImages = canche.shouldDecompressImages;canche.shouldDecompressImages = NO;SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader];SDImagedownloderOldShouldDecompressImages = downloder.shouldDecompressImages;downloder.shouldDecompressImages = NO;

3、dell中恢复原设置:

-(void)dealloc {    SDImageCache *canche = [SDImageCache sharedImageCache];    canche.shouldDecompressImages = SDImageCacheOldShouldDecompressImages;    SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader];    downloder.shouldDecompressImages = SDImagedownloderOldShouldDecompressImages;}
号外:苹果官方给出了一个下载高清大图的demo,内存消耗很低。感兴趣的朋友也可以看看:
https://developer.apple.com/library/ios/samplecode/LargeImageDownsizing/Introduction/Intro.html    PS :以上解决方案参考cocoChina上面的一篇文章
tableView优化
有关tableVirew 的优化 请看博主的第一篇博客 也就是置顶的那一个。。。。

离屏渲染是好的还是坏的
相比于当前屏幕渲染,离屏渲染的代价是很高的,这也是iOS移动端优化的必要部分
OpenGL中,GPU屏幕渲染有以下两种方式:
1.当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行。
2.离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
一般情况下,OpenGL会将应用提交到Render Server的动画直接渲染显示(基本的Tile-Based渲染流程),但对于一些复杂的图像动画的渲染并不能直接渲染叠加显示,而是需要根据Command Buffer分通道进行渲染之后再组合,这一组合过程中,就有些渲染通道是不会直接显示的;Masking渲染需要更多渲染通道和合并的步骤;而这些没有直接显示在屏幕的上的通道就是Offscreen Rendering Pass。
Offscreen Render为什么卡顿,Offscreen Render需要更多的渲染通道,而且不同的渲染通道间切换需要耗费一定的时间,这个时间内GPU会闲置,当通道达到一定数量,对性能也会有较大的影响。

离屏渲染的触发

离屏渲染可以被 Core Animation 自动触发,或者被应用程序强制触发。屏幕外的渲染会合并渲染图层树的一部分到一个新的缓冲区,然后该缓冲区被渲染到屏幕上。

离屏渲染合成计算是非常昂贵的, 但有时你也许希望强制这种操作。一种好的方法就是缓存合成的纹理/图层。如果你的渲染树非常复杂(所有的纹理,以及如何组合在一起),你可以强制离屏渲染缓存那些图层,然后可以用缓存作为合成的结果放到屏幕上。

如果你的程序混合了很多图层,并且想要他们一起做动画,GPU 通常会为每一帧(1/60s)重复合成所有的图层。当使用离屏渲染时,GPU 第一次会混合所有图层到一个基于新的纹理的位图缓存上,然后使用这个纹理来绘制到屏幕上。现在,当这些图层一起移动的时候,GPU 便可以复用这个位图缓存,并且只需要做很少的工作。需要注意的是,只有当那些图层不改变时,这才可以用。如果那些图层改变了,GPU 需要重新创建位图缓存。你可以通过设置 shouldRasterize 为 YES 来触发这个行为。

然而,这是一个权衡。第一,这可能会使事情变得更慢。创建额外的屏幕外缓冲区是 GPU 需要多做的一步操作,特殊情况下这个位图可能再也不需要被复用,这便是一个无用功了。然而,可以被复用的位图,GPU 也有可能将它卸载了。所以你需要计算 GPU 的利用率和帧的速率来判断这个位图是否有用。-------------PS : 摘自cocochina的一篇文章







阅读全文
0 0
原创粉丝点击