iOS——单例模式

单例模式是什么

单例模式,就是在一个应用程序中,对应的一个类只会有一个实例,无论创建多少次,都是同一个对象。这样就可以避免重复创建,节省内存。
一般在程序中,经常调用的类,如工具类、公共跳转类等都会采用单例模式。
在程序中,一个单例类在程序中只能初始化一次,为了保证在使用中始终都是存在的,所以单例是在存储器的全局区域,在编译时分配内存,只要程序还在运行就会一直占用内存,在APP结束后由系统释放这部分内存。

系统提供的单例类

UIApplication(应用程序实例类)
NSNotificationCenter(消息中心类)
NSFileManager(文件管理类)
NSUserDefaults(应用程序设置)
NSURLCache(请求缓存类)
NSHTTPCookieStorage(应用程序cookies池)

单例模式代码实现

static id *manager;

@implementation Manager

+ (Manager *)sharedManager {
	if(!manager) {
		manager = [[self allocWithZone:NULL] init];
	}
	return manager;
}
//用alloc返回唯一实例
+ (id)allocWithZone:(NSZone *)zone {
    return [[self sharedManager] retain];
}
//对对象使用copy返回唯一实例
-(id)copyWithZone:(NSZone *)zone {
    return [[self sharedManager] retain];
}
//对对象使用mutablecopy返回唯一实例
-(id)mutableCopyWithZone:(NSZone *)zone {
    return [[self sharedManager] retain];
}

@end

注意:此代码没有使用GCD,只适用于单线程,如果在多线程中使用将会创建多个实例。苹果官方推荐使用GCD,这样无论使用多线程还是单线程,都只执行一次, 在安全的前提下也保证了性能。

Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。

为什么要重写allocWithZone:而不是alloc

首先为了保持单例类实例的唯一性,需要覆盖所有会生成新的实例的方法。这也是为什么要重写copyWithZone:方法和mutableCopyWithZone:方法。那么为什么不重写alloc方法而要重写allocWithZone:方法呢?

平时我们在初始化一个对象的时候,[[Class alloc] init],其实是做了两件事:alloc 给对象分配内存空间,init是对对象的初始化,包括设置成员变量初值等等。而给对象分配空间,除了alloc方法之外,还有另一个方法: allocWithZone:
在NSObject这个类的官方文档里面,allocWithZone:方法介绍中描述到,该方法的参数是被忽略的,正确的做法是传nil或者NULL参数给它。而这个方法之所以存在,是历史遗留原因。
alloc底层是调用allocWithZone:方法的,所以我们只需重写allocWithZone:方法,也能把alloc这条路堵上。如果改为重写alloc,当初始化这个单例类时不使用alloc,而是直接 allocWithZone:, 这个单例就不再是单例了。

单例的优缺点

·优点

  1. 提供了对唯一实例的受控访问,出现问题可以快速定位
  2. 由于在系统内存中只存在一个对象,因此可以节约系统资源,同时避免某些对象的频繁创建和销毁,提高系统的性能

· 缺点

  1. 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难
  2. 由于单例会一直占用系统内存,滥用单例将带来一些负面问题
  3. 单例类的职责过重,在一定程度上违背了“单一责任原则”

SRP(single responsibility principle),即单一责任原则,是一种计算机编程原则,规定每个模块或类只对软件提供的功能的一部分负责,并且该职责应完全由类封装。其所有服务应与该职责严格一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值