記憶體最佳化之封裝九宮格,記憶體最佳化封裝九宮
隨著市場上越來越多的APP上線,好多軟體對手機的記憶體要求也是很大,所以我們在開發的時候一定要掌握如何去最佳化記憶體,將自己的APP儘可能最佳化。今天我們就一起看一下九宮格的最佳化。下面是軟體的
1、為了達到更好的效果我們不用UITableView,首先我們要通過XIB自訂一個圖片和文字
2、自訂主視圖JRMainScrollView,通過協議代理來實現功能,做法和UITableView類似,大家可以參考一下UITableView
首先:我們要定義資料來源協議
//資料來源協議@protocol JRMainScrollDataSource <NSObject>//擷取總的數量- (NSInteger) numberOfItems;//擷取列的數量- (NSInteger) numberOfColumsOfRow;//擷取item- (UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger) index;@end
其次:我們要定義屬性協議
//屬性協議@protocol JRMainScrollDelegate <NSObject>@optional//擷取高度- (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView;//擷取寬度- (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView;//擷取間距- (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type;@end
注意擷取間距包括到左右的間距和上下的間距通過定義一個枚舉實現
typedef enum{ kJRMainScrollItemLeftSpace, kJRMainScrollItemTopSpace} kJRMainScrollItemSpace;
3、內部布局實現,計算出當前所有的frame,並且放入數組在此期間,用的的屬性參數都需要從代理來擷取,代碼如下
//載入子視圖- (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;}
4、判斷當前的frame是不是在當前的螢幕可視範圍之內,如果要是在的進行視圖的渲染,如果不在不予理睬。
-(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; }
5、操作緩衝池重複利用對象
/** 存放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;}
6、在主控制器載入視圖並實現代理方法即可
//載入所有資料- (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; }
想要瞭解更多內容的小夥伴,可以點擊查看源碼,親自運行測試。
疑問諮詢或技術交流,請加入官方QQ群: (452379712)
作者:傑瑞教育
出處:http://www.cnblogs.com/jerehedu/
本文著作權歸煙台傑瑞教育科技有限公司和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。