设计模式:单例

ARC下:

Tools.h文件:

#import <Foundation/Foundation.h>

@interface Tools : NSObject<NSCopying, NSMutableCopying>

// 1.一般情况下,创建一个单例对象都有一个与之对应的类方法
// 2.一般情况下,创建单例对象的方法名称都以share开头,或以default开头
+(instancetype)shareInstance;

@end
View Code

Tools.m文件:

#import "Tools.h"

@implementation Tools

// 一般都以share或default方法开头的方法,都是创建单例的方法
+(instancetype)shareInstance{
    Tools *instance = [[self alloc] init];
    return instance;
}

static Tools *_instance = nil;// 定义一个全局的静态变量

//对象创建的时候,调用alloc方法的时候,就会调用allocWithZone方法
//所以我们只需要在该方法中控制对象只被创建一次即可实现单例
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    /*
    // 以下代码在多线程中,可能会出现问题
    // 单线程就采用以下的写法
//    NSLog(@"%s",__func__);
//    // 由于所有的创建方法都会调用该方法,所以只需要在该方法中控制当前对象只创建一次即可
//    if (_instance == nil) {
//        NSLog(@"创建一个对象");
//        _instance = [[super allocWithZone:zone] init];
//    }
//    return _instance;
     */


    // 以下代码在多线程中也能保证只执行一次
    // 多线程就采用以下的写法
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}

//copyWithZone方法被调用,说明对象已经创建成功了,既然对象已经有了,说明_instance也就有值了。
- (id)copyWithZone:(nullable NSZone *)zone{
//    Tools *t = [[[self class] allocWithZone:zone] init];
//    return t;
    // 改成:
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone{
//    Tools *t = [[[self class] allocWithZone:zone] init];
//    return t;
    // 改成:
    return _instance;
}

@end
View Code

MRC下:

Tools.h文件:

#import <Foundation/Foundation.h>

@interface Tools : NSObject<NSCopying, NSMutableCopying>

+(instancetype)shareInstance;

@end
View Code

Tools.m文件:

#import "Tools.h"

@implementation Tools

+(instancetype)shareInstance{
    Tools *instance = [[Tools alloc] init];
    return instance;
}

static  Tools *_instance = nil;
// 调用alloc方法时,会调用allocWithZone方法
// 所以只要控制在这个方法中,只能创建一个唯一的对象,即可实现单例
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    /*
    if (_instance == nil) {
        _instance = [[super allocWithZone:zone] init];
        //不能通过 [[alloc] init]来创建,不然会发生死循环
    }
    return _instance;
     */

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}

// 实现copy中的方法
- (id)copyWithZone:(nullable NSZone *)zone{
    return _instance;
}

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

// 在MRC下,如果要控制只能有一个对象,则就不能让这个对象释放
-(oneway void)release{
    //这里什么都不做即可,即可保证整个过程中只有一份实例
}

-(instancetype)retain{
    return _instance;
}

-(NSUInteger)retainCount{
    //return 1;

    // 注意:为了方便程序员之间的沟通,一般情况下不会在单例中返回retainCount = 1,而是返回一个比较大的数值
    // 这样做,就知道这个对象就只有一份实例
    return MAXFLOAT;
}

@end
View Code

main.m文件:

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

int main(int argc, const char * argv[]){

    Tools *tool = [Tools shareInstance];

    [tool release];

    return 0;
}
View Code

ps:自己慢慢琢磨。。。。。。

原文地址:https://www.cnblogs.com/KeenLeung/p/5123818.html