zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    (005)Linux 复制命令cp总提示是否覆盖的解决方法,在cp前加
    (030)Spring Boot之RestTemplate访问web服务案例
    Gym
    Gym
    Gym.102006:Syrian Collegiate Programming Contest(寒假自训第11场)
    BZOJ-5244 最大真因数(min25筛)
    HDU
    HDU 1272 小希的迷宫(并查集)
    HDU 3038 How Many Answers Are Wrong(带权并查集)
    POJ 1182 食物链(带权并查集)
  • 原文地址:https://www.cnblogs.com/yaowen/p/7443685.html
Copyright © 2011-2022 走看看