标签:申请 声明 lock 静态变量 manage dem zone struct 意义
UIApplication(应用程序实例类)
NSNotificationCenter(消息中心类)
NSFileManager(文件管理类)
NSUserDefaults(应用程序设置)
NSURLCache(请求缓存类)
NSHTTPCookieStorage(应用程序cookies池)
官方说法:
一个类必须只有一个对象。客户端必须通过一个众所周知的入口访问这个对象。
这个唯一的对象需要扩展的时候,只能通过子类化的方式。客户端的代码能够不需要任何修改就能够使用扩展后的对象。
举例说明:在建模的时候,如果这个东西确实只需要一个对象,多余的对象都是无意义的,那么就考虑用单例模式。比如,存储用户信息的用户管理类,在登录成功后,其它各个业务模块都可能用到。所以就会考虑用单例。
在单例A中创建m属性,这个属性在单例A的init方法中进行初始化,初始化的时候m属性依赖于另一个单例B创建。而单例B中创建了n属性,这个属性在单例B的init中进行初始化,初始化的时候n属性依赖于前面的单例A创建。这样创建出来会使用其中一个单例进行初始化的时候会出现死锁问题。
解决方法
设计的时候就尽量不去产生这种互相依赖的关系。
如果真的产生这种依赖关系就适当的打破死锁链。
实在要形成环或者无法控制,那么就异步初始化的方式,先过去,内容再填,内部需要做个标识,标识这个单例创建的是时候不能立即被使用或者不能完整被使用。
位 置 | 存放的变量 |
---|---|
栈 | 临时变量(由编译器管理自动创建/分配/释放的,栈中的内存被调用时处于存储空间中,调用完毕后由系统系统自动释放内存) |
堆 | 通过alloc、calloc、malloc或new申请内存,由开发者手动在调用之后通过free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存,在ARC模式下,由系统自动管理。 |
全局区域 | 静态变量(编译时分配,APP结束时由系统释放) |
常量 | 常量(编译时分配,APP结束时由系统释放) |
代码区 | 存放代码 |
单例对象一旦建立,对象指针保存在静态区,单例对象在堆中分配的内存空间,只在应用程序终止后才会被释放
1. 单例模式创建的对象能够一直存在于内存中不被释放,并不只是由于持有一个自身的引用,本质是因为这个引用是静态,也就是说,如果成员变量是非静态的,它持有一个自身的引用,那么这个对象还是被回收。
2. "系统内至少保持一个对象的引用",这个引用指的是从栈区或方法区中发出的引用,也就是安全的引用
3. 类被实例化之后,是放在堆区中的,而我们是无法直接操作堆内存的,因此需要一个引用,指向堆区的某个区域,而这个引用,必须是从栈中(或方法区中)发出的,因为我们可以直接访问栈内存,如果是从堆中发出的引用,是无意义的引用,我们根本访问不到,因此会被回收。
4. 在程序中,一个单例类在程序中只能初始化一次,为了保证在使用中始终都是存在的,所以单例是在存储器的全局区域,在编译时分配内存,只要程序还在运行就会一直占用内存,在APP结束后由系统释放这部分内存内存。
@interface SingletonClass : NSObject + (instancetype)shareInstance; @end
.m
+ (instancetype)shareInstance { return [[super alloc]init]; } /** * @see 使用alloc方法初始化一个类的实例的时候,默认是调用了allocWithZone的方法 */ + (instancetype)allocWithZone:(struct _NSZone *)zone { static SingletonClass *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [super allocWithZone:zone]; }); return instance; }
二,demo
单例
标签:申请 声明 lock 静态变量 manage dem zone struct 意义
原文地址:https://www.cnblogs.com/lxlx1798/p/11481096.html