- 不要等到明天,明天太遥远,今天就行动。
须读:看完该文章你能做什么?
能处理ARC和MRC单例的操作
学习前:你必须会什么?(在这里我已经默认你具备C语言的基础了)
什么是ARC,什么是MRC
一、本章笔记
一、单例设置模式
1.确保只有一个对象
2.重写copy,mutableCopy方法
3.MRC 重写 retain、release、retainCount方法
二、code
main.m
#pragma mark 21-单例ARC和MRC写法
#pragma mark - 代码
#import <Foundation/Foundation.h>
#pragma mark 类
#import "Tools.h"
#pragma mark - main函数
int main(int argc, const char * argv[])
{
/*
// 单例就是 无论怎么创建 都只能有一个实例对象
// 如果地址相同 就代表着是 同一个实例对象
Tools *t1 = [[Tools alloc]init]; // 内部会调用allocWithZone
Tools *t2 = [Tools new];
Tools *t3 = [Tools shareInstance];
Tools *t4 = [Tools copy];
Tools *t5 = [Tools mutableCopy];
NSLog(@"%p,%p,%p,%p,%p",t1,t2,t3,t4,t5);
*/
Tools *t = [[Tools alloc]init];
[t retain];
[t retain];
[t retain];
NSLog(@"t = %p",t);
NSLog(@"retainCount = %lu",[t retainCount]);
[t release];
Tools *t1 = [Tools shareInstance];
NSLog(@"t1 = %p",t1);
NSLog(@"retainCount = %lu",[t1 retainCount]);
[t1 release];
return 0;
}
Person
>>>.h
#import <Foundation/Foundation.h>
@interface Tools : NSObject<NSCopying,NSMutableCopying>
// 一般情况下 创建一个单例对象 都有一个与之对应的类方法
// 一般情况下 用于创建单例对象的方法名称 都以share开头,或者default开头
+ (instancetype)shareInstance;
@end
>>>.m
#import "Tools.h"
@implementation Tools
+ (instancetype)shareInstance
{
Tools *instance = [[self alloc]init];
return instance;
}
static Tools *_instance = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
#pragma 1.当前代码在多线程中 可能会出现问题
/*
NSLog(@"%s",__func__);
// 由于所有的创建方法都会调用,所以只需要在爱方法中控制当前对象 只创建一次即可
if (_instance == nil) {
NSLog(@"创建了一个对象");
_instance = [super allocWithZone:zone];
}
return _instance;
*/
// 一下代码在多线程 也能保证执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return _instance;
}
#pragma mark MRC需要多处理
- (oneway void)release
{
// 为了保证整个程序过程中 只有一份实例
// 在这个方法中什么都不做
}
- (instancetype)retain
{
return _instance;
}
- (NSUInteger)retainCount
{
// return 1;
// 注意 : 为了方便程序员之间沟通,一般情况下 不会在单例中返回 retainCount = 1;
// 而是返回一个比较大的值
return MAXFLOAT;
}
@end