随着市场上越来越多的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. 程序猿的量化交易之路(18)--Cointrader之Event实体(6)

    转载需注明: 事件,是Esper的重要概念. 这里我们定义个事件类.它是Temporal实体的派生类. 不过对Temporal简单的包装.其代码例如以下: package org.cryptocoin ...

  2. 关于wait notify notifyall的学习心得

    wait()能让同步的线程挂起并将锁抛出,sleep只能使线程“睡了“,线程的锁并不会抛出,所以sleep还可以作用于非同步的线程.notify与notifyall能将被挂起或睡着的线程唤醒,但并不是 ...

  3. Word技巧杂记(二)——批量修改修订格式并接受

    今天的题目好奇怪啊,呵呵,起因如下: 今天老婆在修改论文,她的老板提出一个非常**的要求——把Word中所有修订后的文字用特殊的字体(蓝色)标出来,然后再接受修订.我勒个去,明明有修订后的模式啊,为什 ...

  4. Word技巧杂记(一)——去掉页眉上方的黑线

    今天在调整文章的格式时,突然发现在页眉的上方有一条巨粗无比的黑线,不知从何处冒出来的(如下图) 经过长时间的研究,终于发现原来这是页面的边框.解决办法也很简单: 格式->边框与底纹->页面 ...

  5. android WebViewClient和WebChromeClient

    一.Android之WebViewClient与WebChromeClient的区别 ANDROID应用开发的时候可能会用到WEBVIEW这个组件,使用过程中可能会接触到WEBVIEWCLIENT与W ...

  6. 【POJ 2182】Lost Cows

    [题目链接] http://poj.org/problem?id=2182 [算法] 树状数组 + 二分 [代码] #include <algorithm> #include <bi ...

  7. js 智能识别收获地址

    项目地址https://github.com/wzc570738205/smart_parse 支持以下数据格式 马云,1351111111,北京市朝阳区姚家园3楼 马云1351111111北京市朝阳 ...

  8. POJ 3185 DFS

    好像可以用高斯消元??? 但是用搜索写 这题就很水了... // by SiriusRen #include <bitset> #include <cstdio> using ...

  9. 压力测试工具 Tinyget

    Tinyget 压力测试工具使用方法为:命令行切换到工具所在路径下,然后输入压力命令.如:tinyget -srv:localhost -uri:/FeaturedProdu1cts.aspx -th ...

  10. ES6的基本语法

    ES6 详细参考页面 简介 ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现.一般来说,这两个词是可以互换的. let命令 ES6新增了let命令,用来声明变 ...