zoukankan      html  css  js  c++  java
  • 设计模式:单例

    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:自己慢慢琢磨。。。。。。

  • 相关阅读:
    html 的一些基础操作
    java 通过反射调用属性,方法,构造器
    java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包
    java 反射,类的加载过程以及Classloader类加载器
    java 随机读写访问流及seek方法
    java 序列化机制
    java 标准输入输出流,打印流,数据流
    hp400 硒鼓加粉图解
    Delphi XE5 android 获取网络状态
    Delphi XE5 常见问题解答
  • 原文地址:https://www.cnblogs.com/KeenLeung/p/5123818.html
Copyright © 2011-2022 走看看