定义:
享元模式是 一种 可共享 对象的一种设计模式。在需要使用大量的细粒度 对象的过程中。这种模式 能很大的减少内存和提升性能。
所谓 细粒度,就是对象相近 而且 数量很多。 我们把这些对象 分成 内部状态 和 外部状态。 内部状态 只使用一个对象来共享,外 部 。外部状态 不能共享出来,是对象区分的。
大体实现:
实现享元模式需要两个关键组件,通常是可共享的享元对象和保存他们的池。某种中央对象维护这个池,并从它返回适当的实例。
在中 demo下载地址中: https://github.com/LoveHouLinLi/ShareElement_DesginMode。 介绍了基本原理 WebSiteFactory 类:是管理池 和 获取共享对象的类 WebSiteFactory中 的 flyweights 就是存储 不同的
共享对象的池。DLConcreteWebSite 类:创建共享对象的 类 User:代表代表了 共享的外部状态 这里使用 执行WebSiteProtocol 协议 使用。
第一个基本定义分析:
WebSiteFactory *factory = [[WebSiteFactoryalloc]init];
webSiteType type1 = [factorygetWebSiteCategory:@"首页"];
User *user1 = [[Useralloc]init];
user1.userName = @"张三";
[type1 use:user1];
webSiteType type2 = [factorygetWebSiteCategory:@"iOS"];
User *user2 = [[Useralloc]init];
user2.userName = @"德龙";
[type2 use:user2];
webSiteType type3 = [factorygetWebSiteCategory:@"Java"];
User *user3 = [[Useralloc]init];
user3.userName = @"Developer";
[type3 use:user3];
NSInteger count = [factorygetWebSiteCount];
NSLog(@"个数: %ld", (long)count); // 3
webSiteType type4 = [factorygetWebSiteCategory:@"Java"];
User *user4 = [[Useralloc]init];
user4.userName =@"new Java Developer";
[type4 use:user4];
NSInteger count2 = [factorygetWebSiteCount];
NSLog(@"个数: %ld", (long)count2); // 3
注意 type4 和 type3 实际上是同一个共享的元素。 外部的变量 User 可以是不同的。这样 就不要重复的创建。
二: 我们DEMO中 在屏幕中随机显示花朵图案,屏幕中填满花朵“百花池”。但是实际上只使用了6个不同的花朵视图的实例。
在 方法
- (void)hundredsFlowers
{
DLFlowerFactory *factory = [[DLFlowerFactoryalloc]init];
NSMutableArray *flowerList = [[NSMutableArrayalloc] initWithCapacity:600];
DLFlyweightView *flyweightView = [[DLFlyweightViewalloc] initWithFrame:self.view.bounds];
[self.viewaddSubview:flyweightView];
for (int i =0 ; i<600; i++)
{
FlowerType flowerType =arc4random()%kTotalNumberOfFlowerTypes;
UIView *flowerView = [factoryflowerViewWithType:flowerType];
CGRect screenBounds = [[UIScreenmainScreen] bounds];
// 随机的位置 随机的view 的10 - 50 之间的大小的 view
CGFloat x = (arc4random() % (NSInteger)screenBounds.size.width);
CGFloat y = (arc4random() % (NSInteger)screenBounds.size.height);
NSInteger minSize = 10;
NSInteger maxSize = 50;
CGFloat size = (arc4random() % (maxSize - minSize + 1)) + minSize;
// ExtrinsicFlowerState extrinsicState;
// extrinsicState.flowerView = flowerView;
// extrinsicState.area = CGRectMake(x, y, size, size);
DLFlyweightMode *mode = [[DLFlyweightModealloc] init];
mode.flowerView = flowerView;
mode.area = CGRectMake(x, y, size, size);
// [flowerList addObject:[NSValue value:&extrinsicState withObjCType:@encode(ExtrinsicFlowerState)]];
[flowerList addObject:mode];
}
// [(DLFlyweightView *)self.view setFlowerList:flowerList];
[flyweightView setFlowerList:flowerList];
}
我们可以随便更改 600 为 500 或者 2000 等 发现内存并没有跟着涨 因为我们复用了 flowerView.
这里如果你打开 我写的demo的话 ,你会 发现 DLFlowerView 和 DLFlyweightView 都是使用 drawRect 的方法来绘制 图片。 而不是直接使用UIImageView 设置 image 然后 加在父视图上呢?