oc84--单利

//  Tools.h

#import <Foundation/Foundation.h>

@interface Tools : NSObject<NSCopying, NSMutableCopying>
// 一般情况下创建一个单例对象都有一个与之对应的类方法,一般情况下用于创建单例对象的方法名称都以share开头, 或者以default开头
+ (instancetype)shareInstance;

@end
//
//  Tools.m


#import "Tools.h"

@implementation Tools

+ (instancetype)shareInstance
{
    Tools *instance = [[self alloc] init];//调用allocWithZone
    return instance;
}

static Tools *_instance = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone  //alloc内部会调用allocWithZone
{
    // 由于所有的创建方法都会调用该方法, 所以只需要在该方法中控制当前对象只创建一次即可
    
    /*
    // 当前代码在多线程中可能会出现问题
    NSLog(@"%s", __func__);
    if (_instance == nil) {
        NSLog(@"创建了一个对象");
        _instance = [[super allocWithZone:zone] init];  //去父类创建,不能用self否则会死循环,
    }
    return _instance;
     */
    
    // 以下代码在多线程中也能保证只执行一次
    static dispatch_once_t onceToken;//long类型
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}

// copyWithZone方法用什么调用? 对象,对象已经有了,就用原来的对象。
- (id)copyWithZone:(NSZone *)zone{
//    Tools *t = [[[self class] allocWithZone:zone] init];  //调用allocWithZone,所以这里也是单利,
//    return t;
    return _instance;
}

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










//MRC:MRC才可以写release,retain,retainCount
- (oneway void)release
{
    // 为保证整个程序过程中只有一份实例, 在这个方法中什么都不做,单利释放了就没有了。
}

- (instancetype)retain
{
    return _instance;
}

- (NSUInteger)retainCount
{
//    return 1;
    // 注意: 为了方便程序员之前沟通, 一般情况下不会在单例中返回retainCount = 1
    // 而是返回一个比较大得值
    return  MAXFLOAT;
}


@end
//
//  main.m
//  单例:只有一个实例,只有程序挂掉实例才释放。
//

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

int main(int argc, const char * argv[]) {
    
//ARC
    // 单例就是无论怎么创建都只能有一个实例对象
    // 如果地址相同就代表着是同一个实例对象
    Tools *t11 = [[Tools alloc] init]; //alloc内部会调用allocWithZone,这里调用allocWithZone,
    Tools *t21 = [Tools new];// [[alloc] init],  allocWithZone,,这里调用allocWithZone,
    Tools *t31 = [Tools shareInstance];//先调用shareInstance再调用allocWithZone,
    
    Tools *t41 = [t31 copy];
    Tools *t51 = [t31 mutableCopy];
    
    NSLog(@"%p, %p, %p, %p, %p", t11, t21, t31, t41, t51);//0x1005035e0, 0x1005035e0, 0x1005035e0, 0x1005035e0, 0x1005035e0
    
    
    
//MRC
    Tools *t2 = [[Tools alloc] init];
    [t2 retain];
    [t2 retain];
    [t2 retain];
    [t2 retain];
    [t2 retain];
    NSLog(@"retainCount = %lu", [t2 retainCount]);//4299163232
    NSLog(@"t2 = %p", t2);//t2 = 0x1005035e0
    [t2 release];
    
    
    Tools *t1 = [Tools shareInstance];
    NSLog(@"retainCount = %lu", [t1 retainCount]);//4299163232
    NSLog(@"t1 = %p", t1);//0x1005035e0
    [t1 release];
    
    
    return 0;
}
原文地址:https://www.cnblogs.com/yaowen/p/7443685.html