第08天OC语言(21):单例ARC和MRC写法

  • 不要等到明天,明天太遥远,今天就行动。
须读:看完该文章你能做什么?

能处理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

推荐阅读更多精彩内容