单例在ARC和MRC中

本文介绍如何在自动引用计数(ARC)和手动引用计数(MRC)环境中实现单例模式。通过定义宏简化重复代码,并详细说明了在不同内存管理模式下所需重写的方法差异。

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

单例在ARC和MRC中

创建一个单例对象,需要做以下几点:
 1.定义一个全局的static类变量instance,赋值为nil
 2.重写allocWithZone方法:内部用dispatch_once来保证线程安全
 3.在MRC中,重写release方法
 4.重写retain方法:直接返回instance
 5.重写copyWithZone和mutableCopyWithZone方法

注意:

alloc方法中默认调用allocWithZone,所以重写的时候,重写allocWithZone即可
内存中只有一份,因此可以定义为static,静态变量在内存中只有一份

在ARC和MRC中,重写方法有所不同,MRC需要对retain,copy等操作进行重写,而ARC不需要.


我们可以动态判断,统一写一个单例xx.h的宏.

定义宏的原因:

1.如果有多个单例对象,那么创建时都需要重新写,可以考虑简化目的.

2.如果以父类的形式定义一个单例父类,那么集成于谁?NSObject?UIView?

创建一个singleTon.h文件

#ifndef __ARC_MRC_singleTon_h
#define __ARC_MRC_singleTon_h

//头部分
#define singleTon_H(name) + (instancetype) share##name

//实现部分
//判断是否是ARC
//ARC
#if __has_feature(objc_arc)

	#define singleTon_M(name) 										\
		+ (instancetype)share##name {								\
			return [[self alloc] init];								\
	}																\
																	\
	static id instance = nil;										\
	+ (instancetype)allocWithZone:(struct _NSZone *)zone {			\
		static dispatch_once_t onceToken;							\
		dispatch_once(&onceToken, ^{								\
			if (instance == nil) {									\
				instance = [super allocWithZone:zone];				\
			}														\
		});															\
		return instance;											\
	}																\
																	\
	- (id)copyWithZone:(struct _NSZone *)zone {						\
		return instance;											\
	}																\
	- (id)mutableCopyWithZone:(NSZone *)zone {						\
		return instance;											\
	}

#else       //MRC
	#define singleTon_M(name) 										\
		+ (instancetype)share##name {								\
			return [[self alloc] init];								\
	}																\
																	\
	static id instance = nil;										\
	+ (instancetype)allocWithZone:(struct _NSZone *)zone {			\
		static dispatch_once_t onceToken;							\
		dispatch_once(&onceToken, ^{								\
			if (instance == nil) {									\
				instance = [super allocWithZone:zone];				\
			}														\
		});															\
		return instance;											\
	}																\
																	\
	- (oneway void)release {										\
	}																\
	- (instancetype)retain {										\
		return instance;											\
	}																\
																	\
	- (id)copyWithZone:(struct _NSZone *)zone {						\
		return instance;											\
	}																\
	- (id)mutableCopyWithZone:(NSZone *)zone {						\
		return instance;											\
	}
#endif

#endif


创建一个Animal的单例对象:

Animal.h

#import <Foundation/Foundation.h>
#import "singleTon.h"

@interface Animal : NSObject
singleTon_H(Animal);
@end

Animal.m

#import "Animal.h"
#import "singleTon.h"

@interface Animal () <NSCopying,NSMutableCopying>
@end

@implementation Animal
singleTon_M(Animal);
@end

调用方法:

程序为MRC中的测试情况,ARC中不需要release操作了.

#import <Foundation/Foundation.h>
#import "Animal.h"

int main(int argc, const char * argv[]) {
	Animal *tool1 = [[Animal alloc] init];
	[tool1 release];
	NSLog(@"tool1 %zd",tool1.retainCount);
	
	Animal *tool2 = [[Animal alloc] init];
	Animal *tool3 = [Animal shareAnimal];
	Animal *tool4 = [tool3 retain];
	Animal *tool5 = [tool3 copy];
	NSLog(@"tool4 %zd",tool4.retainCount);
	NSLog(@"tool5 %zd",tool5.retainCount); 
	NSLog(@"%p %p %p",tool1,tool2,tool3);
	
    return 0;
}
结果如下:
2015-07-01 13:42:34.591 单例ARC-MRC[1098:207060] tool1 1
2015-07-01 13:42:34.592 单例ARC-MRC[1098:207060] tool4 1
2015-07-01 13:42:34.593 单例ARC-MRC[1098:207060] tool5 1
2015-07-01 13:42:34.593 单例ARC-MRC[1098:207060] 0x100112000 0x100112000 0x100112000


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值