单例实现(单例宏)

一、什么是单例

单例就是,一个类,每次创建都是同一个对象。也就是说只能实例化一次。

二、如何保证每次创建都是同一个对象

创建一个对象归根揭底都会经过一个途径,alloc方法(alloc方法会调用allocWithZone:)。因此只要保证alloc方法只会调用一次,且保证线程安全,然后把此对象放在静态区。以后不管是创建对象还是copy对象都直接返回静态区的对象。

三、注意点

静态全局变量不需要考虑释放的问题(适用于MRC),解决线程安全问题可以用互斥锁或者GCD,后者更好。

也可设置不让对象重复初始化,即让初始化方法只能执行一次。

四、具体实现代码如下

@implementation myManager
static id instance;

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    // 1、互斥锁
//        @synchronized (self) {
//            if (instance == nil)
//            {
//                instance = [super allocWithZone:zone];
//            }
//        }

    // 2、GCD,只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (instance == nil)
        {
            instance = [super allocWithZone:zone];
        }
    });
    return instance;
}

+ (instancetype)sharedSoundTools
{
    instance = [[self alloc] init];
    return instance;
}

- (id)copyWithZone:(NSZone *)zone
{
    return instance;
}

#pragma mark - MRC 部分代码
- (oneway void)release
{
    // 什么都不做
}

- (instancetype)retain
{
    // 本想什么都不做,但它要返回值
    return instance;
}

- (instancetype)autorelease
{
    return instance;
}

- (NSUInteger)retainCount
{
    // 此处防治有人不明就里的粗暴释放对象,比如while循环
    return ULONG_MAX;
}

- (instancetype)init
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        self = [super init];
        if (self)
        {
            self.age = 10; // 只是举个例子,只初始化一次,可以不设置
        }
    });
    return self;
}

@end

五、单例宏

以下代码写在单独singleton.h文件里,使用时直接包含.h头文件。

使用方法,.h文件:singletonInterface(myManager);

.m文件:singletonImplementation(myManager);

抽取代码如下:

#define singletonInterface(className)          + (instancetype)shared##className;

#if __has_feature(objc_arc)
// 以下是ARC版本
#define singletonImplementation(className) + (instancetype)allocWithZone:(struct _NSZone *)zone {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         if (instance == nil) {             instance = [super allocWithZone:zone];         }     });     return instance; } + (instancetype)shared##className {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         instance = [[self alloc] init];     });     return instance; } - (id)copyWithZone:(NSZone *)zone {     return instance; }
#else
// 以下是MRC版本
#define singletonImplementation(className) + (instancetype)allocWithZone:(struct _NSZone *)zone {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         if (instance == nil) {             instance = [super allocWithZone:zone];         }     });     return instance; } + (instancetype)shared##className {     static dispatch_once_t onceToken;         dispatch_once(&onceToken, ^{         instance = [[self alloc] init];     });     return instance; } - (id)copyWithZone:(NSZone *)zone {     return instance; } - (oneway void)release {} - (instancetype)retain {return instance;} - (instancetype)autorelease {return instance;} - (NSUInteger)retainCount {return ULONG_MAX;}
#endif

// 提示末尾一行不要有 \
时间: 2024-10-12 17:53:47

单例实现(单例宏)的相关文章

Spring4 In [email protected]单例、多例Bean

Spring In [email protected]单例.多例Bean 代码下载地址:http://download.csdn.net/download/poiuy1991719/9967494 Singleton:单例    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)@Scope("singleton") Prototype:每次注入都会创建新的   @Scope(ConfigurableBeanFactory.SCOPE_PRO

单例和多例的区别

单例和多例的区别 单例多例需要搞明白两个问题:1. 什么是单例多例:2. 如何产生单例多例:3. 为什么要用单例多例4. 什么时候用单例,什么时候用多例:1. 什么是单例.多例:所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action; 一.单例模式和多例模式说明: 1.         单例模式和多例模式属于对象模式. 2.         单例模式的对象在整个系统中只有一份,多例模式可以有多

Java 单例和多例详解

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

spring自动注入是单例还是多例?单例如何注入多例?

单例多例需要搞明白这些问题:      1. 什么是单例多例:      2. 如何产生单例多例:      3. 为什么要用单例多例      4. 什么时候用单例,什么时候用多例:   1. 什么是单例.多例: 所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action; 单例模式和多例模式说明: 1. 单例模式和多例模式属于对象模式. 2. 单例模式的对象在整个系统中只有一份,多例模式可以有

详略。。设计模式2——单例变形(多例).。。。studying

★ 缓存在单例中的使用("单例+缓存"技术) 缓存在编程中使用非常频繁,有着非常关键的数据,它可以帮助程序实现以空间换取时间, 通常被设计成整个应用程序所共享的一个空间,现要求实现一个用缓存存放单例对象的类. 说明:该缓存中能够存放多个该类对象,每一个对象以一个key值标识.key值同样时所訪问的是同一个单例对象. ★ 单例变形--多例模式("单例+缓存+控制实例个数"技术) 把上面缓存的单例实现,做成一个可以控制对象个数的共享空间,供整个应用程序使用. 在缓存中维

SpringMVC Controller单例和多例

对于SpringMVC Controller单例和多例,下面举了个例子说明下. 第一次:类是多例,一个普通属性和一个静态属性. 结果:普通属性:0.............静态属性:0 普通属性:0.............静态属性:1 普通属性:0.............静态属性:2 普通属性:0.............静态属性:3 所以说:对于多例情况普通属性时不会共用的,不会产生影响,对于静态属性会去共用这个属性. 第二次:类改为单例 结果:普通属性:0.............静态属

单例与多例的理解

1. 什么是单例多例:2. 如何产生单例多例:3. 为什么要用单例多例4. 什么时候用单例,什么时候用多例: 1. 什么是单例多例: 所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action; 2. 如何产生单例多例:     在通用的SSH中,单例在spring中是默认的,如果要产生多例,则在配置文件的bean中添加scope="prototype"; 3. 为什么用单例多例:   

springboot默认创建的bean是单实还是多例

转:https://blog.csdn.net/q1512451239/article/details/53122687 springboot默认创建的bean是单实还是多例 曾经面试的时候有面试官问我spring的controller是单例还是多例,结果我傻逼的回答当然是多例,要不然controller类中的非静态变量如何保证是线程安全的,这样想起似乎是对的,但是不知道(主要是我没看过spring的源码,不知道真正的内在意图)为什么spring的controller是单例的. 先看看sprin

IOC的单例和多例

Spring容器在默认情况下管理的bean是单例(singleton)的,即该bean只会创造一个对象,无论之后调用多少次该bean,都只会返回同一个对象. 多例(prototype)模式,每次调用同一个bean,都会创造不同的对象. 实验: 两个实验类: package com.tsvv.pojo; public class Apple { } --------------------------------------- package com.tsvv.pojo; public class

Linux学习笔记——例说makefile 增加宏定义

0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助博客总结makefile的相关知识,通过例子说明makefile的具体用法. 例说makefile大致分为4个部分 1.只有单个C文件 2.含有多个C文件 3.需要包括头文件路径 4.增加宏定义 5.增加系统共享库 6.增加自定义共享库 7.一个实际的例子 [代码仓库]--makefile-example