zoukankan      html  css  js  c++  java
  • Objective-C中的单例模式

     ​单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接触设计模式是通过《漫谈设计模式》了解的。这本书中是用java写的,个人感觉拜读完这本书以后虽然有不理解的地方但还是收获蛮大的。上面提到依赖注入,控制翻转的时候,没大看懂,当学习到Strut,Spring, Hibernate的东西的时候才略懂略懂。不过在23种设计模式里面单例模式还是算比较好理解的, 那么在OC中又是怎么来表示单例模式的呢?下面会结合着代码,理解一下OC中得单例模式。

        ​    ​首先得了解什么是单例模式,用大白话说,单例模式就是在程序中这个类只对应着一个实例,这就是单例模式,单例模式一般用全局静态对象来实现。下面我们会建立一个生成单例的类SingletonClass,在实现文件中定义各种方法来实现我们的单例模式。

        ​    ​1.单例模式一般用全局静态对象来实现,所以我们在SingletonClass.m中定义一个静态全局变量是少不了的

    1
    2
    //定义静态全局变量
    static SingletonClass *single = nil;

        ​    ​2.上面的静态变量是定义在实现文件中的所以是私有的,要想获取该类的实例得有个getInstance方法来获取实例,在给静态变量分配内存空间之前首先要判断是否已经分配过啦,确保单例,如果分配过了就不分配了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //获取静态全局对象
    +(id)getInstance
    {
        //如果没有生成对象,则为静态全局变量分配内存
        if (single == nil) {
            single = [[SingletonClass alloc] init];
        }
        return single;
    }

        ​    ​

        ​    ​3.为了防止用户通过alloc和new来实例化对象,因此我们要对类方法allcoWithZone进行重写

    1
    2
    3
    4
    5
    6
    7
    8
    //防止通过alloc或者new来创建新的对象我们要重写allocWithZone
    +(id)allocWithZone:(NSZone *)zone
    {
        if (single == nil) {
            single = [[super allocWithZone:zone] init];
        }
        return single;
    }

        ​    ​4.为了防止用户把单例进行深浅拷贝,我们需要重写copyWithZone方法和mutableCopyWithZone方法,在重写方法之前我们的单例类必须遵循协议NSCoping和NSMutableCoping协议

        ​    ​遵循协议代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @interface SingletonClass : NSObject<NSCopying, NSMutableCopying>
     
    //单例中获取单例对象的方法
    +(id) getInstance;
     
    //单例测试方法
    -(void) singletonFunction;
     
    @end

        ​    ​重写copyWithZone方法

    1
    2
    3
    4
    5
    //为了防止通过copy来创建新的实例我们要重写copyWithZone;
    -(id)copyWithZone:(NSZone *)zone
    {
        return self;
    }

        ​    ​重写mutableCopyWithZone方法

    1
    2
    3
    4
    -(id)mutableCopyWithZone:(NSZone *)zone
    {
        return self;
    }

        ​5.防止用户把创建的单例dealloc,我们需要重写retainCount方法

    1
    2
    3
    4
    5
    //重写retainCount方法,防止被dealloc,返回最大值
    -(NSUInteger) retainCount
    {
        return NSUIntegerMax;
    }

        ​6. 重写release,autorelease, retain方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //重写retain,引用计数不变
    -(id) retain
    {
        return self;
    }
     
    //重写release
    -(oneway void) release
    {
    }
     
    //重写autorelease
    -(id) autorelease
    {
        return self;
    }

        ​至此我们的单例模式基本创建完毕,下面开始我们的测试吧;

        ​在main函数中的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //单例模式的测试
    SingletonClass *single1 = [SingletonClass getInstance];
    SingletonClass *single2 = [SingletonClass new];
    SingletonClass *single3 = [[SingletonClass alloc] init];
    SingletonClass *single4 = [single1 copy];
    SingletonClass *single5 = [single1 mutableCopy];
    SingletonClass *single6 = [single1 retain];
    [single1 release];
     
    [single1 singletonFunction];
    NSLog(@"single_retainCount = %lu", single1.retainCount);
     
    //输出地址
    NSLog(@"getInstance     single1_P = %p", single1);
    NSLog(@"new             single2_P = %p", single2);
    NSLog(@"allo            single3_P = %p", single3);
    NSLog(@"copy            single4_P = %p", single4);
    NSLog(@"mutableCopy     single5_P = %p", single5);
    NSLog(@"retain          single6_P = %p", single6);

        ​    ​运行结果如下:

    1
    2
    3
    4
    5
    6
    7
    8
    2014-08-07 16:04:44.207 Memory[20664:303] singleton Ps: 我是单例模式中得测试方法!!
    2014-08-07 16:04:44.207 Memory[20664:303] single_retainCount = 18446744073709551615
    2014-08-07 16:04:44.207 Memory[20664:303] getInstance     single1_P = 0x100204690
    2014-08-07 16:04:44.208 Memory[20664:303] new             single2_P = 0x100204690
    2014-08-07 16:04:44.208 Memory[20664:303] alloC            single3_P = 0x100204690
    2014-08-07 16:04:44.208 Memory[20664:303] copy            single4_P = 0x100204690
    2014-08-07 16:04:44.209 Memory[20664:303] mutableCopy     single5_P = 0x100204690
    2014-08-07 16:04:44.209 Memory[20664:303] retain          single6_P = 0x100204690

    ​    ​    ​单例的地址是不变的。

         上面是在非ARC模式下得单例模式,那么在ARC模式下我们应如何实现我们的单例模式呢,我们下面就会给出ARC下的单例模式,用下面的方法,因没有重写alloc,copy等方法,通过alloc还是可以给该对象分配一个新对象的,上面是线程不安全的,下面是线程安全的:

    复制代码
    1 + (id)sharedSingleton {
    2     static MySingleton *sharedSingleton = nil;
    3     static dispatch_once_t onceToken;
    4     dispatch_once(&onceToken, ^{
    5         sharedSingleton = [[self alloc] init];
    6     });
    7     return sharedSingleton;
    8 }
  • 相关阅读:
    微人事项目-mybatis-持久层
    通过外键连接多个表
    springioc
    Redis 消息中间件 ServiceStack.Redis 轻量级
    深度数据对接 链接服务器 数据传输
    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
    sqlserver 索引优化 CPU占用过高 执行分析 服务器检查
    sql server 远程备份 bak 删除
    冒泡排序
    多线程 异步 beginInvoke EndInvoke 使用
  • 原文地址:https://www.cnblogs.com/zhangkeyu/p/6659463.html
Copyright © 2011-2022 走看看