socket套接字的格式
- int socket (int domain, int type, int protocol); //成功:返回套接字描述符;失败:-1
- 套接字的特性有三个属性:域(domain),类型(type),和协议(protocol)。套接字还用地址作为它的名字。地址的格式随域(又被称为协议族,protocol family)的不同而不同。每个协议族又可以使用一个或多个地址族定义地址格式。
socket半包 粘包 是什么 以及怎么解决
粘包:粘包就是多组数据被一并接收了,粘在了一起,无法做划分
半包:半包就是有数据接收不完整,无法处理
以下是代码解决方法:
- - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
- {
- while (_readBuf.length >= 10)//因为头部固定10个字节,数据长度至少要大于10个字节,我们才能得到完整的消息描述信息
- {
- NSData *head = [_readBuf subdataWithRange:NSMakeRange(0, 10)];//取得头部数据
- NSData *lengthData = [head subdataWithRange:NSMakeRange(6, 4)];//取得长度数据
- NSInteger length = [[[NSString alloc] initWithData:lengthData encoding:NSUTF8StringEncoding] integerValue];//得出内容长度
- NSInteger complateDataLength = length + 10;//算出一个包完整的长度(内容长度+头长度)
- if (_readBuf.length >= complateDataLength)//如果缓存中数据够一个整包的长度
- {
- NSData *data = [_readBuf subdataWithRange:NSMakeRange(0, complateDataLength)];//截取一个包的长度(处理粘包)
- [self handleTcpResponseData:data];//处理包数据
- //从缓存中截掉处理完的数据,继续循环
- _readBuf = [NSMutableData dataWithData:[_readBuf subdataWithRange:NSMakeRange(complateDataLength, _readBuf.length - complateDataLength)]];
- }
- else//如果缓存中的数据长度不够一个包的长度,则包不完整(处理半包,继续读取)
- {
- [_socket readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据
- return;
- }
- }
- //缓存中数据都处理完了,继续读取新数据
- [_socket readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据
- }
加载高清大图内存暴涨 是因为大图是高清的 分辨率很高 解压缩过程中造成的。解压缩操作中,每一个像素点都会分配一个空间来存储相关值,那么分辨率越高的图片,就意味着更多数量的像素点,也就意味着需要分配更多的空间!所以对于高分辨率图来说,解压缩操作的确会造成内存飙升,即使是几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上面的一篇文章
离屏渲染的触发
离屏渲染可以被 Core Animation 自动触发,或者被应用程序强制触发。屏幕外的渲染会合并渲染图层树的一部分到一个新的缓冲区,然后该缓冲区被渲染到屏幕上。
离屏渲染合成计算是非常昂贵的, 但有时你也许希望强制这种操作。一种好的方法就是缓存合成的纹理/图层。如果你的渲染树非常复杂(所有的纹理,以及如何组合在一起),你可以强制离屏渲染缓存那些图层,然后可以用缓存作为合成的结果放到屏幕上。
如果你的程序混合了很多图层,并且想要他们一起做动画,GPU 通常会为每一帧(1/60s)重复合成所有的图层。当使用离屏渲染时,GPU 第一次会混合所有图层到一个基于新的纹理的位图缓存上,然后使用这个纹理来绘制到屏幕上。现在,当这些图层一起移动的时候,GPU 便可以复用这个位图缓存,并且只需要做很少的工作。需要注意的是,只有当那些图层不改变时,这才可以用。如果那些图层改变了,GPU 需要重新创建位图缓存。你可以通过设置 shouldRasterize 为 YES 来触发这个行为。
然而,这是一个权衡。第一,这可能会使事情变得更慢。创建额外的屏幕外缓冲区是 GPU 需要多做的一步操作,特殊情况下这个位图可能再也不需要被复用,这便是一个无用功了。然而,可以被复用的位图,GPU 也有可能将它卸载了。所以你需要计算 GPU 的利用率和帧的速率来判断这个位图是否有用。-------------PS : 摘自cocochina的一篇文章