IOS-单例模式

原创 2015年11月19日 13:47:42

单例模式可以保证在程序运行的过程中,一个类只有一个实例方法,而且该实例易于供外界访问。例如,oc中的 UIApplication 可以通过 [UIApplication sharedApplication] 方法开速实例化一个UIApplication对象,而且在整个项目中仅实例化一份,即只有一个内存地址。

单例模式可以分为两类:(1)懒汉式,第一次用到这个单例对象的时候,再创建;(2)饿汉式,一进入程序就创建一个单例对象。在实际上一般都是“懒汉式”的单例模式,因为当项目中的单例对象较多时,如果使用“饿汉式”​单例模式,会导致程序在一启动就加载单例对象,或许项目中的很多单例一开始更不用不到,这样就消耗了不必要的内存。所以,一般选取“懒汉式”的单例模式,这样在需要的时候,再创建单例对象。

实现单例对象步骤可以归纳为:

(1)提供全局变量;

(2)重写allocWithZone方法,(这是alloc底层调用的方法)

(3)提供类方法sharedClassName​(其中ClassName为对象的名称),方便其他开发人员快速调用。

(4)重写copyWithZone方法。

如果是非ARC环境,基于上述步骤还要重写retain、retainCount、autorelease和release方法。​

实现单例对象可以采用两种方式:一种是互斥锁访问,一种是GCD实现。

互斥锁实现单例模式:

static id _instance;
//这里的static修饰全局变量,使得全局变量的作用域仅限于当前文件内,保证安全​
//重写allocWithZone方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone{

    if (_instance == nil) {//保证只加一次锁,方式重复加锁

        @synchronized(self) {//加锁,多线程安全

            if (_instance == nil) {//防止创建多次

                _instance = [super allocWithZone:zone];
            }
        }
    }
    return _instance;
}
//实现外部调用的shared方法
+ (instancetype)sharedMusicTool{
    if (_instance == nil) {
        @synchronized(self) {
            if (_instance == nil) {
                _instance = [[self alloc] init];
            }
        }
    }
    return _instance;
}
//实现copyWithZone方法
- (id)copyWithZone:(NSZone *)zone{
    return _instance;
}
//非ARC要实现
- (oneway void)release{
}

- (instancetype)retain{
    return self;
}
- (NSUInteger)retainCount{
    return 1;
}
- (instancetype)autorelease{
    return self;
}

GCD实现单例模式:

static id _instance;
//这里的static修饰全局变量,使得全局变量的作用域仅限于当前文件内,保证安全​
//重写allocWithZone方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
	static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{//代码仅被执行一次
        _instance = [super allocWithZone:zone];
    });          
    return _instance;
}
//实现外部调用的shared方法
+ (instancetype)sharedMusicTool{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{//代码仅被执行一次
        _instance = [[self alloc] init];
    });   
    return _instance;
}
//实现copyWithZone方法
- (id)copyWithZone:(NSZone *)zone{
    return _instance;
}
//非ARC要实现
- (oneway void)release{
}

- (instancetype)retain{
    return self;
}
- (NSUInteger)retainCount{
    return 1;
}
- (instancetype)autorelease{
    return self;
}

每次实现都用这段代码实现单例对象时,代码重复率高,因此定义一个专门实现单例对象的宏,其他单例对象直接调用单例的宏定义即可,简化了代码。宏定义为:

//.h文件
#define XCSingleModelH(name) + (instancetype)shared##name;

//.m文件
//ARC环境
#if __has_feature(objc_arc)
//ARC环境
#define XCSingleModelM(name) \
static id _instance; \
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
 \
+ (instancetype)shared##name{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [[self alloc] init]; \
    }); \
    return _instance; \
} \
 \
- (id)copyWithZone:(NSZone *)zone{ \
    return _instance; \
}
#else

//MRC环境,非ARC环境
#define XCSingleModelM(name) \
static id _instance; \
 \
+ (instancetype)allocWithZone:(struct _NSZone *)zone{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
 \
+ (instancetype)shared##name{ \
    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 self; \
} \
 \
- (NSUInteger)retainCount{ \
    return 1; \
} \
 \
- (instancetype)autorelease{ \
    return self; \
}
#endif

当定义一个单例对象的时候,可以引入宏定义:

.h文件:

#import <Foundation/Foundation.h>
#import "<span style="font-family: Arial, Helvetica, sans-serif;">SingleHod</span>.h"

@interface ClassName : NSObject

SingleHod(ClassName);

@end
.m文件:
<pre name="code" class="objc">#import "ClassName.h"
#import "SingleHod.h"

@implementation ClassName

SingleHod(ClassName);

@end







版权声明:本文为博主原创文章,欢迎转载,请注明出处。

相关文章推荐

iOS单例模式

  • 2015-08-01 17:34
  • 62KB
  • 下载

iOS 单例模式

  • 2013-08-21 12:18
  • 119KB
  • 下载

iOS开发中的单例模式

介绍单例模式已经如何在iOS中创建单例

IOS单例模式Demo

  • 2015-08-10 13:40
  • 66KB
  • 下载

iOS 单例模式的介绍和写法

创建一个单例很多办法。我先列举一个苹果官方文档中的写法。   [cpp] view plaincopy static AccountManager *Defa...

ios单例模式demo

  • 2013-10-30 10:41
  • 76KB
  • 下载

IOS_单例模式

  • 2015-05-26 17:11
  • 426B
  • 下载

iOS-单例模式

iOS-单例模式 何为单例模式,就是说如果在一个应用程序中,如果你想让一个类的实例使用的都是同一个,这时你就把该类设置为单例模式,iOS基础框架中有很多的单例模式类,如NSUse...

IOS_单例模式(ARC).

  • 2015-05-26 17:09
  • 424B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)