`
折句号
  • 浏览: 11545 次
文章分类
社区版块
存档分类
最新评论

iOS单例模式

 
阅读更多
  1. 单例模式的作用
    可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
    从而方便地控制了实例个数,并节约系统资源

  2. 单例模式的使用场合
    在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次),一般用于工具类。例如:登陆控制器,网络数据请求,音乐播放器等一个工程需要使用多次的控制器或方法。

  3. 单例模式的优缺点
    优点:
    单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
    如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
    单例模式因为类控制了实例化过程,所以类可以更加灵活修改实例化过程。

    缺点:
    单例对象一旦建立,对象指针是保存在静态区的,单例对象在堆中分配的内存空间,会在应用程序终止后才会被释放。
    单例类无法继承,因此很难进行类的扩展。
    单例不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。

注意:我们在使用单例类之前,一定要考虑好单例类是否适合和类以后的扩展性,避免盲目滥用单例

 

ARC中单例实现步骤

 

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

#import "Tools.h"

@implementation Tools
// 创建静态对象 防止外部访问
static Tools *_instance;
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
//    @synchronized (self) {
//        // 为了防止多线程同时访问对象,造成多次分配内存空间,所以要加上线程锁
//        if (_instance == nil) {
//            _instance = [super allocWithZone:zone];
//        }
//        return _instance;
//    }
    // 也可以使用一次性代码
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    });
    return _instance;
}
// 为了使实例易于外界访问 我们一般提供一个类方法
// 类方法命名规范 share类名|default类名|类名
+(instancetype)shareTools
{
    //return _instance;
    // 最好用self 用Tools他的子类调用时会出现错误
    return [[self alloc]init];
}
// 为了严谨,也要重写copyWithZone 和 mutableCopyWithZone
-(id)copyWithZone:(NSZone *)zone
{
    return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}

三. 单例在MRC中的实现

MRC单例实现步骤

1 在类的内部提供一个static修饰的全局变量
2 提供一个类方法,方便外界访问
3 重写+allocWithZone方法,保证永远都只为单例对象分配一次内存空间
4 严谨起见,重写-copyWithZone方法和-MutableCopyWithZone方法
5 重写release方法
6 重写retain方法
7 建议在retainCount方法中返回一个最大值

配置MRC环境

1 注意ARC不是垃圾回收机制,是编译器特性
2 配置MRC环境:build setting ->搜索automatic ref->修改为N0

MRC中单例代码实现
配置好MRC环境之后,在ARC代码基础上重写下面的三个方法即可

-(oneway void)release
{

}
-(instancetype)retain
{
    return _instance;
}
-(NSUInteger)retainCount
{
    return MAXFLOAT;
}

四. 一劳永逸,单例模式的优化

如果想要一劳永逸,我们将面临两个问题
1:如何写一份单例代码在ARC和MRC环境下都适用?
2:如何使一份单例代码可以多个类共同使用
为了解决这两个问题,我们可以在PCH文件使用代参数的宏和条件编译
利用条件编译来判断是ARC还是MRC环境

#if __has_feature(objc_arc)
//如果是ARC,那么就执行这里的代码1
#else
//如果不是ARC,那么就执行代理的代码2
#endif

注意:单例模式不可以使用继承,因为使用继承,同时也会继承静态变量,当子类和父类同时创建的时候只会创建一个先创建的实例对象。
废话不多说了直接上代码
PCH文件Single.h

#define singleH(name) +(instancetype)share##name;

#if __has_feature(objc_arc)

#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
#define singleM static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
\
+(instancetype)shareTools\
{\
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

这时我们就可以一劳永逸,任何项目中,当我们要使用单例类的时候只要在项目中导入PCH文件然后
在.h文件中调用singleH(类名)
在.m文件中调用singleM(类名)
创建类时直接调用share类名方法即可。

@implementation WMSVoicePickingController
static WMSVoicePickingController *sharedVoicePickingController = nil;

+(WMSVoicePickingController *)shareVoicePicking{
    if (sharedVoicePickingController == nil) {
        sharedVoicePickingController = [[WMSVoicePickingController alloc] init];
    }
    return sharedVoicePickingController;
}

+(void)cleanVoicePicking{
    if (sharedVoicePickingController) {
        sharedVoicePickingController = nil;
    }
}

 

分享到:
评论

相关推荐

    谈一谈iOS单例模式

    以下是对iOS单例模式的详细解释: 1. **单例模式的实现步骤** - **步骤1**:首先,你需要创建一个类方法,通常以`shared`、`default`或`current`开头,用于返回该类的实例。例如,`+ (instancetype)sharedInstance...

    ios单例模式demo

    在iOS开发中,单例模式是一种常见的设计模式,它用于在整个应用程序中确保某一个类只有一个实例存在,并提供一个全局访问点。这样的设计可以方便地管理共享资源,如网络连接、数据库连接或者设置对象等。本Demo是...

    IOS单例模式调试代码

    对于“iOS单例模式调试代码”这个标题,我们可以假设这个压缩包包含了一个用于演示如何调试单例模式的项目。调试单例模式主要关注以下几个方面: 1. **确认唯一性**:确保在程序的任何地方,调用单例的`...

    IOS单例模式Demo

    在iOS开发中,单例模式被广泛应用于管理共享资源、配置设置或者在整个应用程序生命周期内需要持续存在的对象,如网络请求管理者、用户偏好设置等。 在iOS中实现单例模式,通常有几种常见方法: 1. **GCD (Grand ...

    ios 单例模式

    ios单例模式的详细解释、两种方式实现单例模式,重写需要实现的方法

    IOS官方标准_单例模式

    单例模式是软件设计模式中的一种,它在iOS开发中被广泛应用,特别是在管理全局资源、配置或者需要跨类共享的对象时。单例模式的核心思想是确保一个类只有一个实例,并提供一个全局访问点,使得所有对象都可以通过这...

    IOS 单例设计模式实例Demo

    单例模式在iOS中的常见应用场景包括: - **偏好设置(NSUserDefaults)**:保存和读取用户偏好设置。 - **网络请求管理**:统一管理网络请求,如AFNetworking的`sharedManager`。 - **数据库操作**:SQLite、...

    iOS 单例模式

    在iOS开发中,单例模式是一种常见的设计模式,它确保一个类在整个应用程序中只有一个实例,并提供全局访问点。单例模式常用于管理共享资源,如网络连接、偏好设置或者数据库连接,确保这些资源在程序中的统一管理和...

    ios9 单例模式区分arc与非arc宏的使用

    在iOS开发中,单例模式是一种常见的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在iOS 9中,无论是使用ARC(Automatic Reference Counting)还是非ARC,都可以实现单例,但实现方式有所不同。本篇将...

    iOS单例传值

    在iOS应用中,特别是当你想要在多个视图之间传递数据时,单例模式是一个常见且实用的选择。 首先,让我们理解什么是单例。在Objective-C中,单例的实现通常通过以下步骤: 1. 创建一个静态实例变量,用于存储单例...

    设计模式 For iOS-02-单例模式

    单例模式是一种常用的软件设计模式,特别是在iOS开发中,它确保一个类仅有一个实例,并提供一个全局访问点。iOS SDK中广泛应用了单例模式,比如UIApplication和NSFileManager等类就是以单例形式存在。 在iOS开发中...

    Objective C 单例模式设计源码

    顾名思义,单例模式的特点就是保证一个类仅有一个实例。因为这个模式只和一个类有关,没有类与类之间的关系,所有就不给出图示了。那么还是先说一下基本的定义。 单例模式(Singleton),保证一个类仅有一个实例,并...

    ios 单例demo

    单例模式的核心在于限制类的实例化,确保在整个应用程序生命周期内只有一个对象存在。在Objective-C中,我们通常通过以下步骤创建一个单例: 1. **声明一个共享实例**:首先,在单例类的头文件(.h)中声明一个静态...

    IOS应用源码——单例模式.zip

    在iOS应用开发中,单例模式是一种常用的软件设计模式,它保证了类只有一个实例,并提供一个全局访问点。这个模式在iOS中尤其常见,因为许多系统服务和组件就是通过单例来实现的,例如UIApplication、NSFileManager等...

    IOS应用源码之单例模式 .rar

    在iOS应用开发中,单例模式是一种常用的软件设计模式,它保证了类只有一个实例,并提供一个全局访问点。这个模式在iOS中尤其常见,因为许多系统服务和组件就是通过单例来实现的,例如UIApplication、NSFileManager和...

    设计模式ForiOS-02-单例模式.pdf

    这种模式在iOS开发中非常常见,因为许多系统类如UIApplication、NSFileManager等都采用了单例模式。 1.0.1. 什么是单例模式? 单例模式的主要目的是控制类的实例化过程,限制类的实例只有一个。通过一个全局的静态...

    ios应用源码之单例模式 2018127

    在iOS应用开发中,单例模式被广泛用于管理共享资源、配置信息或提供全局服务。例如,网络请求管理器、用户偏好设置、数据库连接等通常会采用单例模式来实现。 在iOS开发中,我们通常使用Objective-C或者Swift来编写...

Global site tag (gtag.js) - Google Analytics