博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS中的单例模式
阅读量:5823 次
发布时间:2019-06-18

本文共 3398 字,大约阅读时间需要 11 分钟。

在程序运行中,一个类只有一个实例,就叫单例。当我们想要在整个应用程序中,指定一份资源只能被初始化一次,并且实现共享的时候我们就可以使用单例模式,也就是创建一个单例类,用它来管理指定资源。

####一、如何在创建一份ARCMRC通用的单例?

  1. 在类的内部提供一个static修饰的全局变量
  2. 提供一个类方法,方便外界访问
  3. 重写+allocWithZone方法,保证永远都只为单例对象分配一次内存空间
  4. 严谨起见,重写-copyWithZone方法和-MutableCopyWithZone方法

如果是MRC则还需要以下步骤: 5. 重写release方法 6. 重写retain方法 7. 建议在retainCount方法中返回一个最大值

我们来看一下代码:

////  STSingleton.m//  单例模式////  Created by Swift Gao on 16/6/24.//  Copyright © 2016年 Swift Gao. All rights reserved.//#import "STSingleton.h"@implementation STSingletonstatic STSingleton *_instance;//保证只分配一次存储空间+(instancetype)allocWithZone:(struct _NSZone *)zone{        //    @synchronized(self) {//        if (_instance == nil) {//            _instance = [super allocWithZone:zone];//        }//    }    static dispatch_once_t onceToken;    dispatch_once(&onceToken,^{        _instance = [super allocWithZone:zone];    });        return _instance;}+(instancetype)shareSTSingleton{    return [[self alloc]init];}- (id)copyWithZone:(NSZone *)zone{    return _instance;}-(id)mutableCopyWithZone:(NSZone *)zone{    return _instance;}#if __has_feature(objc_arc)//ARC//什么都不做#else//MRC//如果用户release了一次,那么什么都不做,因为单例模式在整个程序运行过程中都拥有且//只有一份,程序退出之后被释放,所以不需要对引用计数器操作-(oneway void)release{}//在MRC环境下,如果用户retain了一次,那么直接返回instance变量,不对引用计数器+1-(instancetype)retain{    return _instance;}//惯用法,有经验的程序员通过打印retainCount这个值可以猜到这是一个单例-(NSUInteger)retainCount{    return MAXFLOAT;}#endif@end复制代码

####二、单例类能使用继承吗? 答案是不行的,为什么?

单例类中使用了static修饰的全局变量,继承的时候也会将其继承过来,而这个变量只能创建一次。如果你真的去尝试继承,你会发现,你用父类和子类创建的对象是同一个,继承失去了意义,这并不是我们想要的。

我们使用继承的目的是减少代码量,提高代码的复用以提高开发效率并使得项目结构更加整洁。如果我们也想要使得单例类可以复用,而我们已经知道无法通过继承的方式去实现,那么有没有其他方法?

当然是有的,我们这边使用带参数的宏定义来解决问题。当然,如果有幸让身为大神的你看到这篇文章并且你刚好也有其他更好的解决方案,烦请告知,不胜感激。

创建一个宏定义头文件,直接看代码吧:

////  Singleton.h//  单例模式////  Created by Swift Gao on 16/6/25.//  Copyright © 2016年 Swift Gao. All rights reserved.//#define singleH(name) +(instancetype)share##name;//反斜杠用于拼接跨行//if#if __has_feature(objc_arc)//ARC//define#define singleM(name) static id _instance;\+(instancetype)allocWithZone:(struct _NSZone *)zone{\    static dispatch_once_t onceToken;\    dispatch_once(&onceToken,^{\        _instance = [super allocWithZone:zone];\    });\    return _instance;\}\\+(instancetype)share##name{\    return [[self alloc]init];\}\\- (id)copyWithZone:(NSZone *)zone{\    return _instance;\}\\-(id)mutableCopyWithZone:(NSZone *)zone{\    return _instance;\}//else#else //define#define singleM(name) static id _instance;\+(instancetype)allocWithZone:(struct _NSZone *)zone{\static dispatch_once_t onceToken;\dispatch_once(&onceToken,^{\_instance = [super allocWithZone:zone];\});\return _instance;\}\\+(instancetype)share##name{\return [[self alloc]init];\}\\- (id)copyWithZone:(NSZone *)zone{\return _instance;\}\\-(id)mutableCopyWithZone:(NSZone *)zone{\return _instance;\}\\-(oneway void)release\{\}\\-(instancetype)retain\{\    return _instance;\}\\-(NSUInteger)retainCount\{\    return MAXFLOAT;\}//endif#endif复制代码

如何使用? 如果你要创建一个单例类:Bluetooth

////  Bluetooth.h//  单例模式////  Created by Swift Gao on 16/6/24.//  Copyright © 2016年 Swift Gao. All rights reserved.//#import 
#import "Singleton.h"@interface Bluetooth : NSObject//这里使用了宏定义singleH(Bluetooth)@end复制代码
////  Bluetooth.m//  单例模式////  Created by Swift Gao on 16/6/24.//  Copyright © 2016年 Swift Gao. All rights reserved.//#import "Bluetooth.h"@implementation BluetoothsingleM(Bluetooth)@end复制代码

是的,就这么简单,一次编写,可以到处使用了。

转载地址:http://qqbdx.baihongyu.com/

你可能感兴趣的文章
python调用windows api
查看>>
第四章 mybatis批量insert
查看>>
Java并发框架——什么是AQS框架
查看>>
【数据库】
查看>>
Win配置Apache+mod_wsgi+django环境+域名
查看>>
linux清除文件内容
查看>>
WindowManager.LayoutParams 详解
查看>>
find的命令的使用和文件名的后缀
查看>>
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>
曾鸣:区块链的春天还没有到来| 阿里内部干货
查看>>
如何通过Dataworks禁止MaxCompute 子账号跨Project访问
查看>>
js之无缝滚动
查看>>
Django 多表联合查询
查看>>
logging模块学习:basicConfig配置文件
查看>>
Golang 使用 Beego 与 Mgo 开发的示例程序
查看>>
ntpdate时间同步
查看>>
+++++++子域授权与编译安装(一)
查看>>
asp.net怎样在URL中使用中文、空格、特殊字符
查看>>
路由器发布服务器
查看>>