小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
通过问题看本质!!!
概念
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
iOS使用场景
在iOS开发中,我们经常会用到享元模式,最典型的案例就是UITableViewCell。享元模式也是池技术,重用对象必定会有一个缓存池。比如Java中的JDBC连接池。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];
//随机颜色
UIColor *randomRGBColor = [[UIColor alloc] initWithRed:arc4random()%256/256.0
green:arc4random()%256/256.0
blue:arc4random()%256/256.0
alpha:0.3];
cell.backgroundColor = randomRGBColor;
}
cell.textLabel.text =[NSString stringWithFormat:@"%@-%@", @(indexPath.section), @(indexPath.row)];
return cell;
}
- 尝试复用现有的同类对象;
- 如果找到匹配的对象,直接使用对象。
- 如果未找到匹配的对象,则创建新对象。
代码实现
我们在开发过程中也可以使用UIScrollView+享元模式实现类似UITableView的功能。我们自己在封装代码的时候可以步骤2和步骤3合并成一个操作。在未匹配到对象时,在内部创建对象直接返回,这样能使调用方能更加简单使用,代码也更加具有封装性。
以下只做享元模式的核心代码演示
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface CLTViewReusePool : NSObject
//从缓存池中获取一个view
-(UIView *)dequeueReusableView;
///充置池子
-(void)resetPool;
@end
#import "CLTViewReusePool.h"
@interface CLTViewReusePool ()
///使用中的池子
@property(nonatomic, strong) NSMutableSet<UIView*> *usingViewSet;
///缓存池子
@property(nonatomic, strong) NSMutableSet<UIView*> *poolViewSet;
@end
@implementation CLTViewReusePool
//从缓存池中获取一个view
-(UIView *)dequeueReusableView{
UIView *view = [self.poolViewSet anyObject];
if (view == nil) {
//view不存在。创建一个view,并添加到使用中的池子里。
view = [[UIView alloc] initWithFrame:CGRectZero];
[self.usingViewSet addObject:view];
}else{
//如果view存在,把它从缓存池移除
[self.poolViewSet removeObject:view];
//添加到使用中的池子里。
[self.usingViewSet addObject:view];
}
return view;
}
//充置池子
-(void)resetPool{
UIView *view = nil;
while ((view = [self.usingViewSet anyObject])) {
//添加到缓存池
[self.poolViewSet addObject:view];
//移除正在使用的池
[self.usingViewSet removeObject:view];
}
}
-(NSMutableSet<UIView *> *)usingViewSet{
if (!_usingViewSet) {
_usingViewSet = [[NSMutableSet alloc] init];
}
return _usingViewSet;
}
-(NSMutableSet<UIView *> *)poolViewSet{
if (!_poolViewSet) {
_poolViewSet = [[NSMutableSet alloc] init];
}
return _poolViewSet;
}
@end
CLTViewController中使用代码
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
[self.view addSubview:scrollView];
self.reusePool = [[CLTViewReusePool alloc] init];
///自行改变frame
[scrollView addSubview:[self.reusePool dequeueReusableView]];
[scrollView addSubview:[self.reusePool dequeueReusableView]];
[scrollView addSubview:[self.reusePool dequeueReusableView]];
}
总结
如果想减少同类对象的创建,降低系统的内存。那么享元模式就是必备良药。