OC单例详解

单例(singleton)


实现单例模式有三个条件:

  1. 类的构造方法是私有的
  2. 类提供一个类方法用于产生对象
  3. 类中有一个私有的自己对象

针对于这三个条件,OC中都是可以做到的

  1. 类的构造方法是私有的
    我们只需要重写allocWithZone方法,让初始化操作只执行一次
  2. 类提供一个类方法产生对象
    这个可以直接定义一个类方法
  3. 类中有一个私有的自己对象
    我们可以在.m文件中定义一个属性即可

  • 可以保证在程序运行过程,一个类只有一个实例
  • 应用场景
    • 某个类经常被使用(节约系统资源)
    • 定义工具类
    • 共享数据
  • 注意点
    • 不要继承单例类

      • 先创建子类永远是子类对象
      • 先创建父类永远是父类对象
  • 单例模式:
    • 懒汉模式 : 第一次用到单例对象的时候再创建
    • 饿汉模式 : 一进入程序就创建一个单例对象

ARC


懒汉模式

 1 #import "Singleton.h"
 2
 3 @implementation Singleton
 4 static id _instance;
 5
 6 /**
 7  *  alloc方法内部会调用这个方法
 8  */
 9 + (instancetype)allocWithZone:(struct _NSZone *)zone{
10     if (_instance == nil) { // 防止频繁加锁
11         @synchronized(self) {
12             if (_instance == nil) { // 防止创建多次
13                 _instance = [super allocWithZone:zone];
14             }
15         }
16     }
17     return _instance;
18 }
19
20 + (instancetype)sharedSingleton{
21     if (_instance == nil) { // 防止频繁加锁
22         @synchronized(self) {
23             if (_instance == nil) { // 防止创建多次
24                 _instance = [[self alloc] init];
25             }
26         }
27     }
28     return _instance;
29 }
30
31 - (id)copyWithZone:(NSZone *)zone{
32     return _instance;
33 }
34 @end

饿汉模式(不常用)

 1 #import "HMSingleton.h"
 2
 3 @implementation Singleton
 4 static id _instance;
 5
 6 /**
 7  *  当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)
 8  */
 9 + (void)load{
10     _instance = [[self alloc] init];
11 }
12
13 + (instancetype)allocWithZone:(struct _NSZone *)zone{
14     if (_instance == nil) { // 防止创建多次
15         _instance = [super allocWithZone:zone];
16     }
17     return _instance;
18 }
19
20 + (instancetype)sharedSingleton{
21     return _instance;
22 }
23
24 - (id)copyWithZone:(NSZone *)zone{
25     return _instance;
26 }
27 @end

GCD实现单例模式

 1 @implementation Singleton
 2 static id _instance;
 3
 4 + (instancetype)allocWithZone:(struct _NSZone *)zone{
 5     static dispatch_once_t onceToken;
 6     dispatch_once(&onceToken, ^{
 7         _instance = [super allocWithZone:zone];
 8     });
 9     return _instance;
10 }
11
12 + (instancetype)sharedSingleton{
13     static dispatch_once_t onceToken;
14     dispatch_once(&onceToken, ^{
15         _instance = [[self alloc] init];
16     });
17     return _instance;
18 }
19
20 - (id)copyWithZone:(NSZone *)zone{
21     return _instance;
22 }
23 @end

非ARC

在非ARC的环境下,需要再加上下面的方法:

  • 重写release方法为空
  • 重写retain方法返回自己
  • 重写retainCount返回1
  • 重写autorelease返回自己
  1. - (oneway void)release { }
  2. - (id)retain { return self; }
  3. - (NSUInteger)retainCount { return 1;}
  4. - (id)autorelease { return self;}
  • 如何判断是否是ARC
1 #if __has_feature(objc_arc)
2
3 //ARC环境
4
5 #else
6
7 //MRC环境
8
9 #endif

时间: 2024-11-08 21:04:43

OC单例详解的相关文章

iOS单例详解

在开发中经常会用到单例设计模式,目的就是为了在程序的整个生命周期内,只会创建一个类的实例对象,而且只要程序不被杀死,该实例对象就不会被释放.下面我们来看看单例的概念.用途.如何创建,以便加深理解. 作用 在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比如在APP开发中我们可能在任何地方都要使用用户的信息,那么可以在登录的时候就把用户信息存放在一个文件里面,这些配置数据由一个单例对象统一读取,然后服务进程中的其他

Java 单例和多例详解

1. 什么是单例多例:所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action;  2. 如何产生单例多例:在通用的SSH中,单例在spring中是默认的,如果要产生多例,则在配置文件的bean中添加scope="prototype";  3. 为什么用单例多例:之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存:之所以用多例,是为了防止并发问题:即一个请求

iOS开发——多线程OC篇&多线程详解

多线程详解 前面介绍了多线程的各种方式及其使用,这里补一点关于多线程的概念及相关技巧与使用,相信前面不懂的地方看了这里之后你就对多线程基本上没有什么问题了! 1——首先ios开发多线程中必须了解的概念: 进程 正在进行中的程序被称为进程,负责程序运行的内存分配 每一个进程都有自己独立的虚拟内存空间 线程 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 可以将耗时的执行路径(如:网络请求)放在其他线程中执行 创建线程的目的就是为了开启一条新的执行路径,运行指定的代

iOS开发——UI篇OC篇&UIStackView详解

UIStackView详解 一.继承关系.遵守协议.隶属框架及可用平台 UIStackView 类提供了一个高效的接口用于平铺一行或一列的视图组合.Stack视图使你依靠自动布局的能力,创建用户接口使得可以动态的调整设备朝向.屏幕尺寸及任何可用范围内的变化.Stack视图管理着所有在它的 arrangedSubviews 属性中的视图的布局.这些视图根据它们在 arrangedSubviews 数组中的顺序沿着 Stack 视图的轴向排列.精确的布局变量根据 Stack 视图的 axis , d

iOS开发——实用技术OC篇&事件处理详解

事件处理详解 一:事件处理 事件处理常见属性: 事件类型 @property(nonatomic,readonly) UIEventType     type; @property(nonatomic,readonly) UIEventSubtype  subtype; 事件产生的时间 @property(nonatomic,readonly) NSTimeInterval  timestamp; 事件传递 - hitTest:withEvent: SWIFT func hitTest(_ po

oc单例

转自:http://www.2cto.com/kf/201412/362291.html 单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路.关于单例模式更多的介绍请参考这篇文章. 单例顾名思义就是说一个类的实例只能有一个,在java.C++这类语言中,可以通过将构造函数私有化来避免对象的重复创建,但是objective-c却不能够这样做,我们需要通过其他机制来达到这个目的.一

以Apache服务器、php语言为例 详解动态网站的访问过程

目前来说,网站页面主要分为静态页面和动态页面,纯静态页面组成的网站现在相对比较少见,大型网站一般使用的是动态网站建站技术,还有一部分网站是静态网页与动态网页共存, 本文以Apache服务器.php语言为例,详解动态网站的访问过程,下面直接切入本文主题. (1)用户端访问服务器端的html文件 S1:通过本机配置好的DNS域名服务器地址寻找DNS服务器,将网站URL中的Web主机域名解析为Web服务器所在的Linux操作系统(Apache通常与Linux操作系统组合使用)中对应的IP地址. S2:

OC -- 单例设计模式

#import <Foundation/Foundation.h> @interface Person : NSObject + (instancetype)sharePerson; @end @implementation Person + (instancetype)sharePerson{ Person *p = [[Person alloc] init]; return p; } static Person *_instance; + (instancetype)allocWithZo

iOS开发——UI篇OC篇&amp;UICollectionView详解+实例

UICollectionView详解+实例 实现步骤: 一.新建两个类 1.继承自UIScrollView的子类,比如HMWaterflowView * 瀑布流显示控件,用来显示所有的瀑布流数据 2.继承自UIView的子类,比如HMWaterflowViewCell * 代表着瀑布流数据中的一个单元(一个格子) 3.总结 HMWaterflowView和HMWaterflowViewCell的关系实际上类似于 UITableView和UITableViewCell的关系 二.设计HMWater