版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.04.28 |
前言
前面讲了23种设计模式中的前几个,下面我们继续,先看前几篇文章。
1. 23种设计模式(一)
2. 23种设计模式(二)
3. 23种设计模式(三)
4. 23种设计模式(四)
5. 23种设计模式(五)
6. 23种设计模式(六)
7. 23种设计模式(七)
详述
十五、迭代器模式——Iterator
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。OC中迭代器已经实现的很完美了。我简单的举几个例子。
1. 迭代器
NSArray *arr = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
// 创建数组 正序 迭代器
NSEnumerator *arrEnumer1 = [arr objectEnumerator];
// 创建数组 反序 迭代器
NSEnumerator *arrEnumer2 = [arr reverseObjectEnumerator];
// 创建字典 key 迭代器
NSEnumerator *dicKeyEnumer = [dic keyEnumerator];
// 创建字典 对象 迭代器
NSEnumerator *dicObjEnumer = [dic objectEnumerator];
// 获取迭代器中下一个对象
id obj = [arrEnumer1 nextObject];
// 获取迭代器中所有对象
NSArray *array = [arrEnumer2 allObjects];
2. 数组用迭代器遍历
NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
// 获取数组的正序迭代器
NSEnumerator *enu1 = [array objectEnumerator];
// 获取数组的反序迭代器
NSEnumerator *enu2 = [array reverseObjectEnumerator];
// 遍历数组
id obj = nil;
// 正序,获取下一个需要遍历的元素
while (obj = [enu1 nextObject]) {
NSLog(@"%@", obj);
}
// 反序,获取下一个需要遍历的元素
while (obj = [enu2 nextObject]) {
NSLog(@"%@", obj);
}
3. 集合用迭代器
NSSet *set = [NSSet setWithObjects:@5, @23, @3, @8, @21, @33, @18, nil];
NSEnumerator *enu = [set objectEnumerator];
id obj = nil;
while (obj = [enu nextObject]) {
NSLog(@"%@", obj);
}
4. 字典用迭代器
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"value1", @"key1", @"value2", @"key2", nil];
// key 迭代器
NSEnumerator *keyEnumer = [dic keyEnumerator];
id key = nil;
while (key = [keyEnumer nextObject]) {
NSLog(@"%@ = %@", key, [dic objectForKey:key]);
}
// 对象迭代器
NSEnumerator *objEnumer = [dic objectEnumerator];
id obj = nil;
while (obj = [objEnumer nextObject]) {
NSLog(@"%@", obj);
}
结论:直接看代码体会,都能看懂。
十六、单例模式——Singleton
保证一个类仅有一个实例,使它们都可以独立地变化。
我先说一下我们自定义的单例,先看代码。
1. HCDSingleton.h
#import <Foundation/Foundation.h>
@interface HCDSingleton : NSObject
+ (instancetype)sharedInstance;
@end
2. HCDSingleton.m
#import "HCDSingleton.h"
@implementation HCDSingleton
+ (instancetype)sharedInstance
{
static HCDSingleton *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[HCDSingleton alloc]init];
});
return singleton;
}
@end
上面的是我们自定义的单例。 就我本身理解而言,我认为的单例在整个工程中,就相当于一个全局变量,不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个)。“单例模式”是我们在iOS中最常使用的设计模式之一。单例模式不需要传递任何参数,就有效地解决了不同代码间的数据共享问题。
ios中还有很多系统的单例,比如NSUserDefaults就是单例,UIApplication类有一个方法叫sharedApplication也是一个单例,NSNotificationCenter(消息中心) 、NSFileManager(文件管理) 、NSURLCache(请求缓存)、NSHTTPCookieStorage(应用程序cookies池)都是系统单例。
下面我们就说一下单例的实现方式。
1.通过线程加锁实现
+(DBManager *)sharedManager; (.h文件中)
// m文件中的实现:
+ (DBManager *)sharedManager{
Static DBManager *manager = nil;
@synchronized(self){
if(manager == nil){
manager = [[DBManager alloc]init];
}
}
return manager;
}
2. 通过GCD实现单例方法:
+(DBManager *)sharedManager; (.h文件中)
//.m文件中的实现:
+ (DBManager *)sharedManager{
Static DBManager *manager = nil;
static dispatch_once_t token;
dispatch_once(&token,^{
if(manager == nil){
manager = [[DBManager alloc]init];
}
} );
return manager;
}
3. 重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实例的时候不产生一个新实例,
+ (id)allocWithZone:(NSZone *)zone{
@synchronized(self){
if (!manager) {
manager = [super allocWithZone:zone]; //确保使用同一块内存地址
return manager;
}
return nil;
}
}
4. 适当实现copyWithZone,release和autorelease。
- (id)init;
{
@synchronized(self) {
if (self = [super init]){
return self;
}
return nil;
}
}
下面就集中说一下ARC和非ARC下的单例模式设计。
1. ARC中单例设计模式
//.h文件
#import <Foundation/Foundation.h>
@interface Singleton : NSObject
//单例方法
+(instancetype)sharedSingleton;
@end
//.m文件
#import "Singleton.h"
@implementation Singleton
//全局变量
static id _instance = nil;
//单例方法
+ (instancetype)sharedSingleton
{
return [[self alloc] init];
}
//alloc会调用allocWithZone:
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
//只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
//初始化方法
- (instancetype)init
{
// 只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super init];
});
return _instance;
}
//copy在底层 会调用copyWithZone:
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
+ (id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone
{
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return _instance;
}
@end
2. 非ARC下的单例模式设计
//.m文件
#import <Foundation/Foundation.h>
//单例方法
@interface Singleton : NSObject
+ (instancetype)sharedSingleton;
@end
//.m文件
#import "Singleton.h"
@implementation Singleton
//全局变量
static id _instance = nil;
//单例方法
+(instancetype)sharedSingleton
{
//系统的大多数类方法都有做autorelease,所以我们也需要做一下
return [[[self alloc] init] autorelease];
}
//alloc会调用allocWithZone:
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
//只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
//初始化方法
- (instancetype)init
{
// 只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super init];
});
return _instance;
}
- (oneway void)release
{
//什么都不做 保证单例对象不被销毁
}
//返回本身 保证只有一个单例对象
- (instancetype)retain
{
return _instance;
}
//计数器为1 保证只有一个单例对象
- (NSUInteger)retainCount
{
return 1;
}
//copy在底层 会调用copyWithZone:
+ (id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone
{
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return _instance;
}
@end
后记
未完,待续,休息了,谢谢大家。