iOS-设计模式之享元模式

731 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

通过问题看本质!!!

概念

享元模式(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;
}
  1. 尝试复用现有的同类对象;
  2. 如果找到匹配的对象,直接使用对象。
  3. 如果未找到匹配的对象,则创建新对象。

代码实现

我们在开发过程中也可以使用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]];
}

总结

如果想减少同类对象的创建,降低系统的内存。那么享元模式就是必备良药。