IOS设计模式第二篇之单例设计模式

时间:2023-03-08 22:37:55
IOS设计模式第二篇之单例设计模式

现在我们的组件已经有组织了。你需要从其他的地方得到数据,你也可以创建一个API类管理数据这个下个设计模式单例里面介绍。

这个单例设计模式确保这个类仅仅拥有一个实例,并且为这个实例提供一个全局的访问点。当的题词需要的时候他可以用懒加载创建一个单例。

注意:apple用了很多的单例:[NSUserDefaults standardUserDefaults],[UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager]他们都是返回一个单例对象。

我们很想知道为什么如如果有不止一个类的实例存在。代码和内存很便宜多吗?

有些类需要存在一个实例例如:不需要有很多实例存在。除非你想写很多日志文件。或者获得一个全局配置的句柄类:很容易类在线程安全的情况下来共享资源。例如一个配置文件,如果有很多类同时修改这个配置文件。

怎么使用单例设计模式呢?

看看下面的图表类:

IOS设计模式第二篇之单例设计模式

上面的图片展示了一个Logger类有一个单一的属性是单独的一个实例并且有两个方法sharedInstance和 init。

首先一个客户端发送sharedInstance消息这个属性实例还没有实例化,因此你需要给这个类创建一个新的实例并且返回一个引用给他。

然后你调用sharedInstance实例很快返回没有任何初始化。这个逻辑保证你仅仅有一个实例存在任何时候。

我们将要实现这个设计模式通过创建一个单例类来管理专辑数据。

你需要注意一个文件夹叫API在这个项目,你放到这里面的所有的类都是为了你的应用服务的。在这个文件夹里面创建一个继承与NSObject的LibraryAPI类。

打开libraryAPI头文件,写上以下代码:

@interface libraryAPI : NSObject

+(libraryAPI)shareInstance;

@end

然后到libraryAPI.m的实现文件里面@implementation后面写上

+ (LibraryAPI*)sharedInstance

{

// 1

static LibraryAPI *_sharedInstance = nil;

// 2

static dispatch_once_t oncePredicate;

// 3

dispatch_once(&oncePredicate, ^{

_sharedInstance = [[LibraryAPI alloc] init];

});

return _sharedInstance;

}

1:定义一个静态变量来保存你类的实例确保在你的类里面保持全局。

2:定义一个静态的dispatch_once_t变量来确保这个初始化存在一次。

3:用GCD来执行block初始化libraryAPI实例。这是单例设计模式的本质。这个初始化不在被调用这个类已经被初始化。并且是线程安全的。

下次调用sharedInstance,这个代码里面的dispatch_once block不再执行由于已经执行一次,并且之前创建libraryAPI你已经得到一个引用。

注意:如果你想更多了解GCD可以参考 Multithreading and Grand Central Dispatcha和 How to Use Blocks 教程。

现在你有一个单例对象的入口点来管理专辑。下一步创建一个类来管理持久化你的library数据。

在API文件夹里面创建一个继承NSObject的新类PersistencyManager。

在PersistencyManager头文件导入#import "Album.h"

并且在@interface后面写上:

- (NSArray*)getAlbums;

- (void)addAlbum:(Album*)album atIndex:(int)index;

- (void)deleteAlbumAtIndex:(int)index;

以上三个方法的原型是处理专辑的数据。

打开PersistencyManager.m并且添加下面的代码到@implementation后面:

@interface PersistencyManager () {

// an array of all albums

NSMutableArray *albums;

}

给这个类添加一个延展,这是给一个类添加私有方法和属性的一个方式因此别的类是不能访问的。在这里你定义一个NSMutableArray来存储专家数据。这个可变数组的目的是便于添加和删除专辑。

现在在PersistencyManager实现文件里面添加:

- (id)init

{

self = [super init];

if (self) {

// a dummy list of albums

albums = [NSMutableArray arrayWithArray:

@[[[Album alloc] initWithTitle:@"Best of Bowie" artist:@"David Bowie" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png" year:@"1992"],

[[Album alloc] initWithTitle:@"It's My Life" artist:@"No Doubt" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png" year:@"2003"],

[[Album alloc] initWithTitle:@"Nothing Like The Sun" artist:@"Sting" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png" year:@"1999"],

[[Album alloc] initWithTitle:@"Staring at the Sun" artist:@"U2" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png" year:@"2000"],

[[Album alloc] initWithTitle:@"American Pie" artist:@"Madonna" coverUrl:@"http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png" year:@"2000"]]];

}

return self;

}

在init你填充数组和五个样本唱片。

在PersistencyManager添加三个方法:

- (NSArray*)getAlbums

{

return albums;

}

- (void)addAlbum:(Album*)album atIndex:(int)index

{

if (albums.count >= index)

[albums insertObject:album atIndex:index];

else

[albums addObject:album];

}

- (void)deleteAlbumAtIndex:(int)index

{

[albums removeObjectAtIndex:index];

}

此时,您可能想知道PersistencyManager类的由来,因为它不是一个单例。LibraryAPI和PersistencyManager之间的关系将进一步探讨在下一节中,您将看外观设计模式。

来自英文教程翻译谢绝转载!!!未经允许不得转载维权必究!!!