• objective-c 单例


    基本概念

      始终返回一个实例,即一个类始终只有一个实例

    创建单例设计模式的基本步骤

      声明一个单件对象的静态实例,并初始化为nil  

      创建一个类的类方法,生成一个该类的实例,当且仅当这个类的实例为nil时

      覆盖allocWithZone:方法,确保在直接分配和初始化对象时,不会产生另一个对象

      实现NSCopying协议,覆盖retain,reatinCount方法,以此确保单例的状态(非ARC,还要覆盖release和autorelease)

      在多线程的环境中,注意使用@synchronized关键字,确保静态实例被正确的创建和初始化

     

     

    实例代码:

    User.h

    #import <Foundation/Foundation.h>
    
    @interface UserContext : NSObject<NSCopying>
    
    @property(nonatomic,copy)NSString *userName;
    
    
    +(id)shareUserContext;
    
    
    @end

    User.m

    #import "UserContext.h"
    
    static UserContext *Instance = nil;//定义一个静态实例,并初始化为nil
    @implementation UserContext
    
    +(id)shareUserContext{
        @synchronized(self){//线程保护
            if (Instance == nil) {
                Instance = [[[self class] alloc] init];
            }
        }
        return Instance;
    }
    
    #pragma mark - 以下的方法是为了确保只有一个实例对象
    +(id)allocWithZone:(struct _NSZone *)zone{
        if (Instance == nil) {
            Instance = [super allocWithZone:zone];
        }
        return Instance;
    }
    
    //实现Copy协议,返回实例
    -(id)copyWithZone:(NSZone *)zone{
        return Instance;
    }
    
    /*
     
     
                            非ARC下,还需覆盖下面这些方法
    
     
    //返回实例
    -(id)retain{
        return Instance;
    }
    //什么都不做
    -(oneway void)release{
    
    }
    //返回实例
    -(id)autorelease{
        return Instance;
    }
    //返回一个无符号整型范围最大值
    -(NSUInteger)retainCount{
        return UINT_MAX;
    }
     
    */
    
    @end

    main.m

    #import <Foundation/Foundation.h>
    #import "UserContext.h"
    int main(int argc, const char * argv[])
    {
    
        @autoreleasepool {
            
            // insert code here...
            NSLog(@"Hello, World!");
            
            UserContext *user = [UserContext shareUserContext];
            UserContext *user2 = [[UserContext alloc] init];
            UserContext *user3 = [user copy];
            user.userName = @"桐人";
            NSLog(@"user:%@",user.userName);
            NSLog(@"user2:%@",user2.userName);
            NSLog(@"user3:%@",user3.userName);
            NSLog(@"");//在这里加入断点,可查看内存地址
        }
        return 0;
    }

    运行结果:

    2014-01-04 11:25:34.611 单例[1427:303] Hello, World!
    2014-01-04 11:25:34.612 单例[1427:303] user:桐人
    2014-01-04 11:25:34.612 单例[1427:303] user2:桐人
    2014-01-04 11:25:34.613 单例[1427:303] user3:桐人
    (lldb) 

    内存地址:

    user2    UserContext *    0x100700190    0x0000000100700190
    user3    UserContext *    0x100700190    0x0000000100700190
    user    UserContext *    0x100700190    0x00000001007
  • 相关阅读:
    Linux Home目录硬盘空间缩减
    test
    ORACLE 数据泵 expdp/impdp
    mysql利用mysqlbinlog命令恢复误删除数据
    LogMiner日志挖掘分析管理
    Oracle 审计测试与总结
    redis 5.0.3 讲解、集群搭建
    联想服务器配置 RAID
    Cenots7对lvm逻辑卷分区大小的调整
    kvm 基本运维命令
  • 原文地址:https://www.cnblogs.com/mo-shou/p/3504656.html
Copyright © 2020-2023  润新知