美文网首页iOSiOS学习搬砖
iOS 中的单例模式

iOS 中的单例模式

作者: 奋斗的菜鸟 | 来源:发表于2015-08-29 21:47 被阅读13588次

在iOS中有很多单例对象,比如UIApplication,UIScreen等等,那我们自己可以实现单例吗?答案是肯定的,请往下看

ARC中的单例实现
//.h文件
#import <Foundation/Foundation.h>
@interface Singleton : NSObject
//单例方法
+(instancetype)sharedSingleton;
@end
//.m文件
#import "Singleton.h"
@implementation Singleton
//全局变量
static id _instance = nil;
//单例方法
+(instancetype)sharedSingleton{
    return [[self alloc] init];
}
////alloc会调用allocWithZone:
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    //只进行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}
//初始化方法
- (instancetype)init{
    // 只进行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super init];
    });
    return _instance;
}
//copy在底层 会调用copyWithZone:
- (id)copyWithZone:(NSZone *)zone{
    return  _instance;
}
+ (id)copyWithZone:(struct _NSZone *)zone{
    return  _instance;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
    return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}
@end
  • 测试代码及运行结果
#import <Foundation/Foundation.h>
#import "Singleton.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Singleton *s1 = [[Singleton alloc]init];
        Singleton *s2 = [Singleton sharedSingleton];
        
        Singleton *s3 = [[Singleton alloc]init];
        Singleton *s4 = [Singleton sharedSingleton];
        Singleton *s5 = [s4 copy];
        NSLog(@"%p %p %p %p %p",s1,s2,s3,s4, s5);
    }
    return 0;
}
运行结果
2015-08-29 21:07:01.869 Singleton-ARC[42202:784939] 0x100114760 0x100114760 0x100114760 0x100114760 0x100114760
非ARC中的单例实现
  • 因为在非ARC中,需要我们自己管理内存,所以实现稍微负责一点
//.m文件
#import <Foundation/Foundation.h>
//单例方法
@interface Singleton : NSObject
+ (instancetype)sharedSingleton;
@end
//.m文件
#import "Singleton.h"

@implementation Singleton
//全局变量
static id _instance = nil;
//单例方法
+(instancetype)sharedSingleton{
    //系统的大多数类方法都有做autorelease,所以我们也需要做一下
     return [[[self alloc] init] autorelease];
}
//alloc会调用allocWithZone:
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    //只进行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}
//初始化方法
-(instancetype)init{
    // 只进行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super init];
    });
    return _instance;
}
- (oneway void)release{
    //什么都不做 保证单例对象不被销毁
}
//返回本身 保证只有一个单例对象
- (instancetype)retain{
    return _instance;
} 
//计数器为1 保证只有一个单例对象
- (NSUInteger)retainCount{
    return 1;
}
//copy在底层 会调用copyWithZone:
+ (id)copyWithZone:(struct _NSZone *)zone{
    return  _instance;
}
- (id)copyWithZone:(NSZone *)zone{
    return _instance;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
    return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}
@end
  • 因为要保证单例对象在程序运行期间一直存在,所以不需要实现release方法和dealloc方法
  • 测试代码及运行结果
#import <Foundation/Foundation.h>
#import "Singleton.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Singleton *s1 = [[Singleton alloc]init];
        Singleton *s2 = [Singleton sharedSingleton];
        
        Singleton *s3 = [[Singleton alloc]init];
        Singleton *s4 = [Singleton sharedSingleton];
        Singleton *s5 = [s4 copy];
        
        
        NSLog(@"%p %p %p %p %p",s1,s2,s3,s4, s5);
        [s1 release];
        [s3 release];
        [s5 release];
        
    }
    return 0;
}
运行结果
2015-08-29 21:01:43.770 Singleton-非ARC[42192:782473] 0x100206880 0x100206880 0x100206880 0x100206880 0x100206880
  • 也可以把上面的代码抽出一个宏,以ARC为例
//.h文件   ##表示拼接字符
#define SingletonH(methodName) +(instancetype)shared##methodName;
//.m文件
#define SingletonM(methodName)\
\
static id _instance = nil;\
+(instancetype)sharedSingleton{\
    return [[self alloc] init];\
}\
+(instancetype)allocWithZone:(struct _NSZone *)zone{\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _instance = [super allocWithZone:zone];\
    });\
    return _instance;\
}\
- (instancetype)init{\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _instance = [super init];\
    });\
    return _instance;\
}\
- (id)copyWithZone:(NSZone *)zone{\
    return  _instance;\
}\
+ (id)copyWithZone:(struct _NSZone *)zone{\
    return  _instance;\
}
  • 以上代码如果有上面不对的地方,敬请纠正,谢谢!

相关文章

  • iOS 单例模式

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

  • 单例

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

  • 单例模式 Singleton Pattern

    单例模式-菜鸟教程 iOS中的设计模式——单例(Singleton) iOS-单例模式写一次就够了 如何正确地写出...

  • iOS单例模式容错处理

    ios 单例模式容错处理 1、单例模式的使用和问题解决 在ios开发的过程中,使用单例模式的场景非常多。系统也有很...

  • 谈一谈iOS单例模式

    这篇文章主要和大家谈一谈iOS中的单例模式,单例模式是一种常用的软件设计模式,想要深入了解iOS单例模式的朋友可以...

  • iOS 单例模式 or NSUserDefaults

    本文内容:iOS的单例模式NSUserDefaults的使用总结:iOS单例模式 and NSUserDefaul...

  • iOS中的单例模式

    iOS开发中常用到2中设计模式,分别是代理模式和单例模式,本文主要介绍下单例模式 单例模式的作用 可以保证在程序运...

  • 单例

    在iOS开发时,总是会遇到单例模式,单例即是一种模式,更是一种思想,单例模式是借鉴了数学中的单集合。就是一个集合中...

  • IOS 设计模式

    IOS开发中几种设计模式:单例模式、观察者模式、MVC模式、代理模式 一、单例模式 场景:确保程序运行期某个类,只...

  • ios 开发中的单例模式

    其实iOS开发中的单例模式无非就是一个类创建的对象在程序中只有一个对象! iOS中的单例模式有分为赖汉式和饿汉式单...

网友评论

  • 7529e3cee684:Do not override allocWithZone: to include any initialization code. Instead, class-specific versions of init... methods.

    This method exists for historical reasons; memory zones are no longer used by Objective-C.
    —— 苹果官方文档
  • 飞羽孟德:宏定义写错了
    static id _instance = nil;\
    +(instancetype)sharedSingleton{\
    return [[self alloc] init];\
    }\

    应该改为 shared##methodName
    WhatHurtsMore:两种写法 一个道理
  • 天真烂漫的孩子:ARC系统自动调用retain,release,不需要重写么?
    + (id)copyWithZone:(struct _NSZone *)zone这个类方法,也需要重写?

本文标题:iOS 中的单例模式

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