美文网首页iOS开发笔记
iOS单例模式之MRC和ARC单例类

iOS单例模式之MRC和ARC单例类

作者: 祥子_HelloWorld | 来源:发表于2019-08-08 16:28 被阅读0次

在iOS的开发中,我经常会用到的一种设计模式:单例模式,目的是让这个对象只实例化一次,在内存中只有一份内存。而且是常驻内存,不会被释放。

手写一个单例也许我们都已经很熟悉,但是真的写的很完善吗,有哪些需要注意的呢?

  • 全局静态实例对象
  • 提供一个供外部调用的类方法
  • 加线程锁,防止重复实例化
  • 重写内存分配方法

下面我们就在MRC和ARC两种模式下看一下单例的写法有什么区别。

MRC单例

首先我们来看一下手动管理内存时的单例是怎么写的:
头文件MRCSingleton.h

//
//  MRCSingleton.h
//  Singleton
//
//  Created by z on 2019/5/23.
//  Copyright © 2019年 com.jzsec. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MRCSingleton : NSObject <NSCopying,NSMutableCopying>

//给外部提供的类方法
+ (instancetype)shareInstance;

@end

NS_ASSUME_NONNULL_END

实现文件MRCSingleton.m

//
//  MRCSingleton.m
//  Singleton
//
//  Created by z on 2019/5/23.
//  Copyright © 2019年 com.jzsec. All rights reserved.
//

#import "MRCSingleton.h"

static MRCSingleton *_instance;

@implementation MRCSingleton

//给外部提供的类方法
+ (instancetype)shareInstance
{
    //加互斥锁解决多线程访问安全问题
//    @synchronized (self)
//    {
//        if (_instance == nil)
//        {
//            _instance = [[MRCSingleton alloc] init];
//        }
//    }
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[MRCSingleton alloc] init];
    });
    
    return _instance;
}

//实例化 分配内存
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //加互斥锁解决多线程访问安全问题
//    @synchronized (self)
//    {
//        if (_instance == nil)
//        {
//            _instance = [super allocWithZone:zone];
//        }
//    }
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    
    return _instance;
}

//实现copy协议
-(id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone
{
    return _instance;
}

- (id)copy
{
    return _instance;
}

-(id)mutableCopy
{
    return _instance;
}

//覆盖与内存相关的方法
- (instancetype)retain
{
    return _instance;
}

- (oneway void)release
{
    
}

- (NSUInteger)retainCount
{
    return UINT_MAX;
}

- (instancetype)autorelease
{
    return _instance;
}

@end
ARC单例

自动管理内存时的单例是怎么写的:
头文件ARCSingleton.h

//
//  ARCSingleton.h
//  Singleton
//
//  Created by z on 2019/5/23.
//  Copyright © 2019年 com.jzsec. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ARCSingleton : NSObject <NSCopying,NSMutableCopying>

//给外部提供的类方法
+ (instancetype)shareInstance;

@end

NS_ASSUME_NONNULL_END

实现文件ARCSingleton.m

//
//  ARCSingleton.m
//  Singleton
//
//  Created by z on 2019/5/23.
//  Copyright © 2019年 com.jzsec. All rights reserved.
//

#import "ARCSingleton.h"

static ARCSingleton *_instance;

@implementation ARCSingleton

//给外部提供的类方法
+ (instancetype)shareInstance
{
    //加互斥锁解决多线程访问安全问题
    //    @synchronized (self)
    //    {
    //        if (_instance == nil)
    //        {
    //            _instance = [[ARCSingleton alloc] init];
    //        }
    //    }
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[ARCSingleton alloc] init];
    });
    
    return _instance;
}

//实例化 分配内存
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //加互斥锁解决多线程访问安全问题
    //    @synchronized (self)
    //    {
    //        if (_instance == nil)
    //        {
    //            _instance = [super allocWithZone:zone];
    //        }
    //    }
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    
    return _instance;
}

//实现copy协议
-(id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone
{
    return _instance;
}

- (id)copy
{
    return _instance;
}

-(id)mutableCopy
{
    return _instance;
}

@end
instancetype 和 id

id我们经常使用,当做一个类型不确定的OC对象,instancetype在一些系统的API里也经常看到,也是当做一个类型不确定的OC对象,那么它和id有什么区别呢?

比如刚才我们ARC单例的类方法,新增一个返回id类型的类方法:

//给外部提供的类方法
+ (instancetype)shareInstance;

//用于区别instancetype的测试方法
+ (id)makeInstance;

//实例方法
- (void)test;

实现:

//用于区别instancetype的测试方法
+ (id)makeInstance
{
    return [[[self class] alloc] init];
}

- (void)test
{
    
}

实例化并调用,此时就会收到警告:

因为shareInstance返回的类型是instancetype,在编译期会进行类型检测,检测到它是ARCSingleton对象,所以识别到test方法;而makeInstance返回的是id类型,不检测对象类型,所以不知道它响应test方法。

相关文章

  • 单例模式(单例宏)

    单例模式 单例模式(arc) 类的实现 调用单例 单例模式(mrc) 除了上边的方法我们在mrc的时候还需要增加一...

  • iOS单例模式之MRC和ARC单例类

    在iOS的开发中,我经常会用到的一种设计模式:单例模式,目的是让这个对象只实例化一次,在内存中只有一份内存。而且是...

  • iOS浅谈单例

    ARC MRC 抽取单例 单例模式是不能使用继承的 具体使用

  • 单例

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

  • iOS 单例模式

    概念相关 (1)单例模式 (2)使用场合 2 ARC实现单例 (1)步骤 (2)相关代码 3 MRC实现单例 (1...

  • The Singleton Pattern 单例模式

    单例模式的作用 单例模式的使用场合 单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码 可以用宏...

  • iOS之单例设计模式

    iOS开发多线程篇—单例模式(ARC\MRC) 简单说明: 设计模式:多年软件开发,总结出来的一套经验、方法和工具...

  • iOS开发中ARC和MRC都可以用的单例模式?

    ** 单例模式- 通用版本(ARC&MRC)** (1)有意思的对话 0...

  • 单例模式

    这篇文章的主要内容包括:1、在ARC中完成一个单例模式的三步2、在MRC中完成一个单例模式的三步3、单例模式通用宏...

  • OC语言day08-21单例ARC和MRC写法 (Single

    pragma mark 单例ARC和MRC写法 (Singleton) pragma mark 概念 pragm...

网友评论

    本文标题:iOS单例模式之MRC和ARC单例类

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