美文网首页iOS开发
iOS编程的单例类

iOS编程的单例类

作者: 单线程Jack | 来源:发表于2019-07-18 17:02 被阅读0次
iOS系统中的一些单例

UIApplication(应用程序实例)
NSNotificationCenter(消息中心)
NSFileManager(文件管理)
NSUserDefaults(应用程序设置)
NSURLCache(请求缓存)
NSHTTPCookieStorage(应用程序cookies池)

单例模式的基本实现

1.懒汉模式

// 1.在该类中定义一个静态的全局变量,防止被外部用extren访问
static id _instance;

/**
 static : 修饰变量
 1> 修饰全局变量
 * 全局变量的作用域仅限于当前文件内部,其他文件不能用extren关键字访问
 2> 修饰局部变量 : 
 * 局部变量的生命周期 跟 全局变量 类似
 * 但是不能改变作用域
 * 能保证局部变量永远只初始化1次,在程序运行过程中,永远只有1分内存
 */
 
/**
 * 2.重写它这个类的llocWithZone:方法,确保只为你这个类分配一次内存地址
 *  alloc方法内部会调用这个方法
 */
+ (id)allocWithZone:(struct _NSZone *)zone
{
    if (_instance == nil) { // 防止频繁加锁
        @synchronized(self) { // 加锁,避免在多线程中出错而创建多个对象
            if (_instance == nil) { // 防止创建多次
                _instance = [super allocWithZone:zone]; 
            }
        }
    }
    return _instance;
}

// 3.提供一个shared方法让外界调用这个单例(一般单例都会提供这个方法),确保只init一次
+ (instancetype)sharedMusicTool
{
    if (_instance == nil) { // 防止频繁加锁
        @synchronized(self) {
            if (_instance == nil) { // 防止创建多次
                _instance = [[self alloc] init];
            }
        }
    }
    return _instance;
}

// 4.重写copyWithZone:方法,避免使用copy时创建多个对象
- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

2.饿汉模式(当类加载到OC运行环境中(内存)时,就会调用一次生成这个单例(一个类只会加载一次))

// 1.在该类中定义一个静态的全局变量,防止被外部用extren访问
static id _instance;

/**
 * 2.重写它这个类的llocWithZone:方法,这里不用加锁,因为程序刚启动,线程还没加载,不会出现线程不安全的问题
 */
+ (id)allocWithZone:(struct _NSZone *)zone
{
            if (_instance == nil) { // 防止创建多次
                _instance = [super allocWithZone:zone];
            }
    return _instance;
}

// 3.提供一个shared方法让外界调用这个单例(一般单例都会提供这个方法)
+ (instancetype)sharedMusicTool
{
    return _instance;
}

// 4.重写copyWithZone:方法,避免使用copy时创建多个对象
- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

// 5.重写load这个类方法,在里面alloc它
// 这个方法在程序启动,加载类的时候会调用一次
+ (void)load
{
  _instance = [[self alloc] init];      
}
用GCD实现单例模式
// 1.
static id _instance;

/**
 * 2.用GCD的dispatch_once方法重写
 */
+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
         _instance = [super allocWithZone:zone];
    });
   return _instance;
}

// 3.
+ (instancetype)sharedMusicTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
         _instance = [[self alloc] init];
    });
    return _instance;
}

// 4.
- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

非ARC下的单例模式

// 前面与ACR一样,接着重写以下方法
// 不做release
- (oneway void)release {
}

// retain之后还是自己一份
- (id)retain {
    return self;
}

// 计数器永远为1
- (NSUInteger)retainCount {
    return 1;
}

// 防止被放进自动计数池释放
- (id)autorelease {
    return self;
}

用宏定义实现单例(适配ARC和MRC)

// 在.h文件使用的宏定义
#define HJSingletonH(name) + (instancetype)shared##name;

#if __has_feature(objc_arc)
// 当前的编译器环境是ARC
// 在.m文件使用的宏定义
#define HJSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
}

#else
// 当前的编译器环境是MRC
// 在.m文件使用的宏定义
#define HJSingletonM(name) \
static id _instace; \
 \
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instace = [super allocWithZone:zone]; \
    }); \
    return _instace; \
} \
 \
+ (instancetype)shared##name \
{ \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instace = [[self alloc] init]; \
    }); \
    return _instace; \
} \
 \
- (id)copyWithZone:(NSZone *)zone \
{ \
    return _instace; \
} \
- (oneway void)release {} \
- (id)retain {return self;} \
- (NSUInteger)retainCount {return 1;} \
- (id)autorelease {return self;}
#endif
代码块
代码块
代码块
代码块
代码块
代码块
代码块

相关文章

  • iOS编程的单例类

    iOS系统中的一些单例 UIApplication(应用程序实例)NSNotificationCenter(消息中...

  • 十一.NSUserDefaults本地保存 移除

    NSUserDefaults是iOS系统提供的一个单例类(iOS提供了若干个单例类),通过类方法standardU...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • iOS 单例模式

    关于单例模式的详解,看完这几篇,就完全了然了。iOS 单例模式iOS中的单例模式iOS单例的写法

  • @sychronized和dispatch_once,以及对单例

    在iOS开发中,经常使用到单例。单例是Cocoa中被广泛使用的设计模式之一。单例使得某个类在整个applicati...

  • 单例对象

    iOS单例模式(Singleton)单例模式的意思就是:只有一个实例;单例模式确保每个类只有一个实例,而且自行实例...

  • ios中的单例模式

    单例的概念 单例类保证了应用程序的生命周期中有且仅有一个该类的实例对象,而且易于外界访问。在iOS中有很多单例类,...

  • NSUserDefaults 存储

    一,NSUserDefaults 介绍 NSUserDefaults iOS系统提供的一个单例类(iOS提供了若...

  • 学习笔记:iOS系统的一些单例类

    iOS系统的单例类:UIApplication(应用程序实例)NSNotificationCenter(消息中心)...

  • ios-设计模式-单例

    1)单例是一种编程思想,一个设计模式,与语言无关在采用了单例对象的应用程序中,需要单例类自行提供实例化单例对象,不...

网友评论

    本文标题:iOS编程的单例类

    本文链接:https://www.haomeiwen.com/subject/nozllctx.html