Android内存优化之封装九宫格
随着市场上越来越多的APP上线,好多软件对手机的内存要求也是很大,所以我们在开发的时候一定要掌握如何去优化内存,将自己的APP尽可能优化。今天我们就一起看一下九宫格的优化。下面是软件的截图

1、为了达到更好的效果我们不用UITableView,首先我们要通过XIB自定义一个图片和文字如图:

2、自定义主视图JRMainScrollView,通过协议代理来实现功能,做法和UITableView类似,大家可以参考一下UITableView
首先:我们要定义数据源协议
<span style="font-family:Arial;font-size:14px;">//数据源协议
@protocol JRMainScrollDataSource <NSObject>
//获取总的数量
- (NSInteger) numberOfItems; //获取列的数量
- (NSInteger) numberOfColumsOfRow;
//获取item
- (UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger) index;
@end</span>
其次:我们要定义属性协议
<span style="font-family:Arial;font-size:14px;">//属性协议
@protocol JRMainScrollDelegate <NSObject>
@optional
//获取高度
- (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView; //获取宽度
- (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView; //获取间距
- (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type;
@end</span>
注意获取间距包括到左右的间距和上下的间距通过定义一个枚举实现
<span style="font-family:Arial;font-size:14px;">typedef enum{
kJRMainScrollItemLeftSpace,
kJRMainScrollItemTopSpace
} kJRMainScrollItemSpace;</span>
3、内部布局实现,计算出当前所有的frame,并且放入数组在此期间,用的的属性参数都需要从代理来获取,代码如下
<span style="font-family:Arial;font-size:14px;">//加载子视图
- (void)_loadSubViews{
//获取总个数和列数
NSInteger totalItems=[self.jrDataSource numberOfItems];
NSInteger colum=[self.jrDataSource numberOfColumsOfRow]; //获取宽度和高度
CGFloat itemWidth=[self.jrDelegate widthForItemAtView:self];
CGFloat itemHeigt=[self.jrDelegate heightForItemAtView:self]; //获取上下间距
CGFloat leftSpace=[self.jrDelegate mainScrollView:self spaceForItemWithType:kJRMainScrollItemLeftSpace];
CGFloat topSpace=[self.jrDelegate mainScrollView:self spaceForItemWithType:kJRMainScrollItemTopSpace]; CGFloat space=(kWidth-2*leftSpace-colum*itemWidth)/(colum-1)+itemWidth; for (int i=0;i<totalItems;i++) {
int clo=i%colum;
int row=i/colum;
CGRect frame=CGRectMake(leftSpace+clo*space, 20+row*(itemHeigt+topSpace), itemWidth, itemHeigt);
[self.array addObject:[NSValue valueWithCGRect:frame]];
}
self.contentSize=CGSizeMake(0, CGRectGetMaxY([[self.array lastObject] CGRectValue]));
self.showsVerticalScrollIndicator=NO; }</span>
4、判断当前的frame是不是在当前的屏幕可视范围之内,如果要是在的进行视图的渲染,如果不在不予理睬。
<span style="font-family:Arial;font-size:14px;">-(void)layoutSubviews{
[super layoutSubviews];
//循环便利获取在屏幕中的frame
for (int i=0;i<self.array.count;i++) {
UIView * tempView=(UIView *)self.current[@(i)];
CGRect rect=[self.array[i] CGRectValue];
if ([self isInScreenWith:rect]) {
if(!tempView){//字典里没有的才需要重重新加载
UIView *view=[self.jrDataSource mainScrollView:self itemAtIndex:i];
view.frame=rect;
[self.current setObject:view forKey:@(i)];
[self addSubview:view];
}
}else if(tempView){//如果存在字典而且不在视线内部的则移除
[self.current removeObjectForKey:@(i)];
[tempView removeFromSuperview];
[self.pool addObject:tempView];
}
}
//判断是不是在视野内部,其中有两种情况,Y值在屏幕内部,或者MAXY值在屏幕内部
- (BOOL) isInScreenWith:(CGRect) frame{
CGFloat setMiny=self.contentOffset.y;
CGFloat setMaxy=self.contentOffset.y+kHeight;
BOOL condition1=frame.origin.y>=setMiny&&frame.origin.y<=setMaxy;
BOOL condition2=CGRectGetMaxY(frame)>=setMiny&&CGRectGetMaxY(frame)<=setMaxy;
if(condition1||condition2){
return YES;
}
return NO;
}</span>
5、操作缓冲池重复利用对象
<span style="font-family:Arial;font-size:14px;">/** 存放frame*/
@property(nonatomic,strong) NSMutableArray * array;
/** 存放当前显示的对象*/
@property(nonatomic,strong) NSMutableDictionary * current;
/** 存放缓冲池对象*/
@property(nonatomic,strong) NSMutableSet * pool;
/**
* 获取重复利用的对象
*
* @param identy <#identy description#>
*
* @return <#return value description#>
*/
- (JRRectView *) dequeueReusedItemWithIdenty:(NSString *) identy{
JRRectView * view=[self.pool anyObject];
if (view!=nil) {
[self.pool removeObject:view];
}
return view;
}</span>
6、在主控制器加载视图并实现代理方法即可
<span style="font-family:Arial;font-size:14px;"> //加载所有数据
- (void) _loadSubviews{ //1 增加滚动视图
JRMainScrollView * mainScroll=[[JRMainScrollView alloc] initWithFrame:self.view.bounds];
mainScroll.jrDataSource=self;
mainScroll.jrDelegate=self;
[mainScroll reloadViews];
[self.view addSubview:mainScroll]; }
#pragma mark - 数据源方法
-(NSInteger)numberOfItems{
return 132;
} -(NSInteger) numberOfColumsOfRow{
return 3;
} -(UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger)index{ JRRectView *cell=[mainScrollView dequeueReusedItemWithIdenty:@"test"];
if (cell==nil) {
cell=[[[NSBundle mainBundle] loadNibNamed:@"rect" owner:nil options:nil] lastObject];
} cell.titleLabel.text=[NSString stringWithFormat:@"下载"];
NSString * imageName=[NSString stringWithFormat:@"%d",arc4random_uniform(20)+256];
UIImage *image=[UIImage imageNamed:imageName];
cell.image.image=image; return cell;
} #pragma mark - 代理方法 //获取高度
- (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView{
return 100;
} //获取宽度
- (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView{
return 90;
} //获取间距
- (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type{ if (type==kJRMainScrollItemLeftSpace) {
return 20;
}else if (type==kJRMainScrollItemTopSpace){
return 20;
}
return 20; }</span>
7、内存优化,除了上面6点,还要懂得源码的优化,一键清除Log(开发日志)信息,一键优化减少加密后原包大小
Android内存优化之封装九宫格的更多相关文章
- ANDROID内存优化——大汇总(转)
原文作者博客:转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! ANDROID内存优化(大汇总——上) 写在最前: 本文的思路主要借鉴了20 ...
- Android内存优化之——static使用篇(使用MAT工具进行分析)
这篇文章主要配套与Android内存优化之——static使用篇向大家介绍MAT工具的使用,我们分析的内存泄漏程序是上一篇文章中static的使用内存泄漏的比较不容易发现泄漏的第二情况和第三种情况—— ...
- ANDROID内存优化(大汇总——中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
- Android内存优化大全(中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
- 大礼包!ANDROID内存优化(大汇总)
写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上把网上搜集的各种内存零散知识点进行汇总.挑选.简化后整理而成. 所以我将本文定义为一个工具类的文章,如果你在A ...
- 【腾讯Bugly干货分享】Android内存优化总结&实践
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智 ...
- Android内存优化(三)详解内存分析工具MAT
前言 在这个系列的前四篇文章中,我分别介绍了DVM.ART.内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT. 1.概述 在进行内存分析时,我们可以使用M ...
- Android内存优化1 了解java内存分配 1
开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...
- Android内存优化(二)DVM和ART的GC日志分析
相关文章 Android内存优化系列 Java虚拟机系列 前言 在Java虚拟机(三)垃圾标记算法与Java对象的生命周期这篇文章中,提到了Java虚拟机的GC日志.DVM和ART的GC日志与Java ...
随机推荐
- Ubuntu16.04编译cmake源码
编译版本:cmake-3.8.0-rc2 为了能够编译出ccmake和cmake-gui,首先需要安装libncurses5-dev sudo apt install libncurses5-dev ...
- poi读取合并单元格
poi读取合并单元格 学习了:http://blog.csdn.net/ycb1689/article/details/9764191 进行了列合并单元格的修正:原来是我自己找错了地方: import ...
- UVA 11542 Square 高斯消元 异或方程组求解
题目链接:点击打开链接 白书的例题练练手. . . P161 #include <cstdio> #include <iostream> #include <algori ...
- Pocket英语语法---六、感官动词接不同的动词表示什么意思
Pocket英语语法---六.感官动词接不同的动词表示什么意思 一.总结 一句话总结:其实进行时一般是表示连续,动词原形一般表示常态,过去分词一般表示被动(或者完成). 感官动词接原型表示动作的一般情 ...
- DNS反射放大攻击分析——DNS反射放大攻击主要是利用DNS回复包比请求包大的特点,放大流量,伪造请求包的源IP地址为受害者IP,将应答包的流量引入受害的服务器
DNS反射放大攻击分析 摘自:http://www.shaojike.com/2016/08/19/DNS%E6%94%BE%E5%A4%A7%E6%94%BB%E5%87%BB%E7%AE%80%E ...
- DatabaseMetaData开发实务
1.总论 在企业开发实务中,数据迁移是经常会遇到的事情,此时,需要搞清楚,源数据库与目的数据库之间表以及表内部各列之间的异同.而有些时候,我们拿到的项目文 档,未必能准确表述各个表的准确结构,即使应用 ...
- 5.文件I/O
1 C标准函数与系统函数的区别 文件的结构体: 1.1 I/O缓冲区 每一个FILE文件流都有一个缓冲区buffer,默认大小8192Byte. 1.2 效率 文件缓冲区会降低效率.这里提供缓冲区主要 ...
- UIPickerView的自定义视图
UIPickerView允许开发者对列表项进行任意定制 开发者只要实现UIPickerViewDelegate协议中的-pickerView:viewForRow:forComponent: reus ...
- 如何解决“因为计算机中丢失php_mbstring.dll”
配置编译环境时,php.exe报系统错误,无法启动此程序,因为计算机中丢失php_mbstring.dll. 在C:\Windows找到php.ini文件,ctrl+f找到extension=php_ ...
- 解析RecyclerView(2)——带顶部View和底部View的RecyclerView
在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...