随着市场上越来越多的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内存优化之封装九宫格的更多相关文章

  1. ANDROID内存优化——大汇总(转)

    原文作者博客:转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! ANDROID内存优化(大汇总——上) 写在最前: 本文的思路主要借鉴了20 ...

  2. Android内存优化之——static使用篇(使用MAT工具进行分析)

    这篇文章主要配套与Android内存优化之——static使用篇向大家介绍MAT工具的使用,我们分析的内存泄漏程序是上一篇文章中static的使用内存泄漏的比较不容易发现泄漏的第二情况和第三种情况—— ...

  3. ANDROID内存优化(大汇总——中)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

  4. Android内存优化大全(中)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

  5. 大礼包!ANDROID内存优化(大汇总)

    写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上把网上搜集的各种内存零散知识点进行汇总.挑选.简化后整理而成. 所以我将本文定义为一个工具类的文章,如果你在A ...

  6. 【腾讯Bugly干货分享】Android内存优化总结&实践

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智 ...

  7. Android内存优化(三)详解内存分析工具MAT

    前言 在这个系列的前四篇文章中,我分别介绍了DVM.ART.内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT. 1.概述 在进行内存分析时,我们可以使用M ...

  8. Android内存优化1 了解java内存分配 1

    开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...

  9. Android内存优化(二)DVM和ART的GC日志分析

    相关文章 Android内存优化系列 Java虚拟机系列 前言 在Java虚拟机(三)垃圾标记算法与Java对象的生命周期这篇文章中,提到了Java虚拟机的GC日志.DVM和ART的GC日志与Java ...

随机推荐

  1. rabbitMQ学习笔记(六) topic类型消息。

    上一节中使用了消息路由,消费者可以选择性的接收消息. 但是这样还是不够灵活. 比如某个消费者要订阅娱乐新闻消息 . 包括新浪.网易.腾讯的娱乐新闻.那么消费者就需要绑定三次,分别绑定这三个网站的消息类 ...

  2. iOS 使用脚本自动化复制target

    有些项目成熟以后,就会有需求自动化配置生成一个全新的项目,不需要再让开发人员手动修改工程文件,将配置化工作直接移交给运维或者配置团队去做 其实按照普通的做法,无非就是在xcode里将目标target ...

  3. linux下jenkins安装

    在安装jenkins之前.首先确认jdk和tomcat,maven已经配置好 详细配置方法,请看的我博客. jdk:jdk的安装与配置 tomcat:tomcat的安装与配置 maven:maven的 ...

  4. angularjs1-2,作用域、代码压缩

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. [jzoj 6101] [GDOI2019模拟2019.4.2] Path 解题报告 (期望)

    题目链接: https://jzoj.net/senior/#main/show/6101 题目: 题解: 设$f_i$表示从节点$i$到节点$n$的期望时间,$f_n=0$ 最优策略就是如果从$i, ...

  6. 13.QT多窗口切换list

    Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); list = ...

  7. linux下解决非本机访问出现的提示

    安装完毕之后发现无法用IP访问,出现以下提示 Access forbidden! New XAMPP security concept: Access to the requested directo ...

  8. BZOJ 4321 DP

    思路: 这个DP太神了- 完全没想到 http://blog.csdn.net/geotcbrl/article/details/49663401 //By SiriusRen #include &l ...

  9. Spring《五》集合的注入方式

    List.Set.Map.Properties 1.List <property name="msg"> <list> <value>gf< ...

  10. 如何版本化你的API?--转

    原文地址:http://www.infoq.com/cn/news/2017/09/How-versioning-API 如何版本化API需要考虑各种实际业务场景,但是一个完备的API应该是: 和客户 ...