iOS 中的单例模式

本文详细介绍了在iOS中如何使用ARC及非ARC环境下实现单例模式。通过具体代码示例展示了单例对象的创建过程,并提供了宏定义简化实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.jianshu.com/p/e535c7575d72

在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;\
}


文/奋斗的菜鸟(简书作者)
原文链接:http://www.jianshu.com/p/e535c7575d72
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值