携手创作,一起成长!这是我参与「日新计划 8 月更文挑战」的第1天,点击检查活动详情


规划形式信任大家都很熟悉了,可是越是根底的东西也越是需求经常的回忆与思考,于是着手写一个温故而知新的规划形式回忆系列。
在 8 月,预备把各个常用的不常用的规划形式都进行一次回忆,并大约聊一下各个形式的特色与在 iOS 中的大约运用场景与情况。

单例形式

1、认识单例形式

首先让咱们先看下关于单例形式的界说(来自于《规划形式》(Addison-Wesley,1994))

一个类有且仅有一个实例,而且自行实例化向整个体系供给。

假如说每一个人都是一个类,那么从他出生开端,他便是日子中的唯一实例,每逢有人要拜访或许联络你的时分,不管别人认识你的时分你是什么状况,他所能联络到的都是现在的你。你本身的状况会在其他当地发生改动,即当你状况改动后,后续一切找到你的,都是看到状况改动后的你。那么,咱们就能够以为每一个人都处于单例形式。

在 iOS 中,体系默认就有许多支持单例办法的当地,例如告诉中心、应用管理、本地保存等,可是一般都归于非严厉的单例形式,也便是你能够运用 [UIApplication sharedApplication] 来获取单例目标,也能够经过 [UIApplication new] 生成一个新的目标,而假如依照准确的单例界说来说,仍旧以 UIApplication 类为例, [UIApplication new][UIApplication sharedApplication] 应该在任何时分返回的目标都是相同的。也便是说不管你怎么操作,只会存在一个实例,不会创立其他的副本内容。

2、什么场景运用单例形式?

  • 当你需求在整个程序的运转周期中,让一个类始终保持同一个实例。则必须运用单例形式;(例如 [UIApplication sharedApplication]
  • 在生命周期中管理数据,例如自界说的管理中心或许[NSUserDefaults standardUserDefaults]
  • 为了节约内存,部分类能够运用单例形式,例如多处运用的图片等。

其实能够理解懒加载的话,信任理解单例形式

3、单例形式的运用

单例形式需求完成一个公共访问的类办法,一般命名为 shared + 类名(例如老演员 sharedApplication )。在该办法的详细完成计划,是引荐经过 dispatch_once 来完成类的实例化。(也便是第五点 demo 所展示的)

能够直接经过重写父类的办法,把分配内存的办法变成只履行一次。从根本上完成了单例。

假如依照严厉的单例写法的话,单例形式总共需求重写五个办法:

+ (instancetype)allocWithZone:(struct _NSZone *)zone
+ (id)copyWithZone:(struct _NSZone *)zone
+ (id)mutableCopyWithZone:(struct _NSZone *)zone
- (id)copyWithZone:(NSZone *)zone
- (id)mutableCopyWithZone:(NSZone *)zone

以确保在任何情况下,都只会存在一种实例。(当然,也能够把这些办法包含 alloc、new、copy、mutableCopy 等办法经过 attribute((unavailable(“invalid”))); 方式直接制止,以确保一定运用 shared 的单例办法)

SingleView.h
#import <Foundation/Foundation.h>
@interface SingleView : NSObject
#pragma mark- method
+ (SingleView *)sharedSingleView;
+ (id)alloc __attribute__((unavailable("invalid, use sharedSingleView instead")));
+ (id)new __attribute__((unavailable("invalid, use sharedSingleView instead")));
- (id)copy __attribute__((unavailable("invalid, use sharedSingleView instead")));
- (id)mutableCopy __attribute__((unavailable("invalid, use sharedSingleView instead")));
@end

详细表现即为:

iOS 设计模式之单例模式

假如只是在自己的项目中运用的话,那么直接完成一个 shared 的类办法根本都能满足需求,由于是自己的内容,代码是受控的,完成并调用即可。而假如是对外的库的话(静态库、动态库),这需求根据详细的事务内容考虑是否需求依照严厉的单例写法来完成了。

4、总结

单例形式是一种十分常见、运用频率也很高的一种规划形式。单例能够在许多场合运用,有时分也能够用来保存数据。

(严厉单例)存在着以下特色:

  1. 节约内存;
  2. 在程序的运转周期中保存数据;
  3. 只能在自己的类中完成实例;
  4. 程序的运转周期中,内存不会被开释;
  5. 类中有且仅有一个实例;

5、demo

SingleView.h
#import <Foundation/Foundation.h>
@interface SingleView : NSObject
#pragma mark- method
+ (SingleView *)sharedSingleView;
@end
SingleView.m
#import "SingleView.h"
@implementation SingleView
#pragma mark- public method
+ (SingleView *)sharedSingleView {
    static SingleView *single = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        single = [[super allocWithZone:NULL] init];
    });
    return single;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [SingleView shareSingleView];
}
+ (id)copyWithZone:(struct _NSZone *)zone {
    return [SingleView shareSingleView];
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone {
    return [SingleView shareSingleView];
}
- (id)copyWithZone:(NSZone *)zone{
    return  [SingleView shareSingleView];
}
- (id)mutableCopyWithZone:(NSZone *)zone{
    return [SingleView shareSingleView];
}
@end