• 单例实现代码(懒汉式)


    单例实现代码(懒汉式)

    .h文件

    1 #import <Foundation/Foundation.h>
    2 
    3 @interface MusicLab : NSObject
    4 
    5 //封装类方法
    6 +(instancetype)shareMusicLab;
    7 
    8 @end

    .m文件

     1 #import "MusicLab.h"
     2 
     3 @interface MusicLab()
     4 
     5 //类延展中创建的实例变量和属性,都不能被其他类中创建的该类对象访问,必须放在.h文件中
     6 
     7 @end
     8 
     9 @implementation MusicLab
    10 
    11 
    12 //搞个全局变量来保存MusicLab类创建的唯一对象. 必须加static,否则别的.m文件可以修改它
    13 static MusicLab *musicObj;
    14 
    15 
    16 //此方法也判断两次,为了防止某个SB不使用单例shareMusicLab方法,直接调用[[MusicLab alloc]init];
    17 //类调用alloc方法,其实是在调用allocWithZone方法
    18 +(instancetype)allocWithZone:(struct _NSZone *)zone{
    19     
    20     if (musicObj == nil) { //此判定是为了每次调用alloc方法时都要加锁
    21         @synchronized(self){
    22             NSLog(@"已经加锁");
    23             if (!musicObj) { //防止多个线程进来判定musicObj=nil,在此之前加锁,进不来。
    24                 musicObj = [super allocWithZone:zone]; //该代码执行完,musicObj就不在是空nil了,
    25             }
    26         }
    27 
    28     }
    29 
    30     return musicObj;
    31 }
    32 
    33 
    34 +(instancetype)shareMusicLab{
    35     
    36     //假设2个线程A.B同时进来,判定musicObj的确是nil,
    37     if(musicObj == nil){ //线程A,B来到这里,但是此线程加锁。假设A加锁后进入,B在外面等待
    38         
    39         @synchronized(self){//线程A加锁后进入
    40             
    41             if (musicObj == nil) {//线程A判定为空,继续执行
    42                 
    43                 musicObj = [[self alloc]init];//线程A创建musicObj对象
    44             }
    45         }//线程A出门,musicObj已经有值了。线程B继续上锁进入,但是此时if (musicObj == nil)不成立,只得返回
    46     }
    47     
    48     return musicObj;
    49     
    50 }
    51 
    52 -(id)copyWithZone:(NSZone *)zone{
    53 
    54     return musicObj;
    55 }
    56 
    57 
    58 
    59 //NSLog遇到%@就会调用该方法,将该方法返回的字符串替代%@后面的值。
    60 //- (NSString *)description{
    61 //    return [NSString stringWithFormat:@"地址:%p",self];
    62 //}
    63 
    64 @end

    ViewController.m文件

     1 //单例: 确保一个类无论调用它多少次,用它创建多少个对象,其创建的都是同一个对象,这些对象调用它内部的属性,得到的都是相同的值
     2 
     3 #import "ViewController.h"
     4 #import "MusicLab.h"
     5 
     6 @interface ViewController ()
     7 
     8 @end
     9 
    10 @implementation ViewController
    11 
    12 - (void)viewDidLoad {
    13     [super viewDidLoad];
    14     
    15     //因为每次创建对象都要调用alloc分配内存,故单例需从alloc方法下手,调用alloc方法,其本质又是调用
    16     MusicLab *musicLab = [[MusicLab alloc]init];
    17     MusicLab *musicLab1 = [[MusicLab alloc]init]; 
    18     MusicLab *musicLab2 = [[MusicLab alloc]init]; //修改代码后只有第一次加锁,后面调用都不加锁,故加锁方法只被打印一次
    19     MusicLab *musicLab3 = [MusicLab shareMusicLab];
    20     MusicLab *musicLab4 = [musicLab2 copy]; //copy方法会调用copyWithZone;
    21     
    22     NSLog(@"
     musicLab地址: %p
     musicLab1地址:%p",musicLab,musicLab1);
    23     NSLog(@"
     musicLab3地址:%p
     musicLab4地址:%p",musicLab3,musicLab4);
    24     
    25 //    NSLog(@"
     musicLab实例变量地址: %p
     musicLab1实例变量地址:%p",musicLab.musics,musicLab1.musics); //同一个类的不同对象调用musics属性返回相同的地址,单例已实现
    26     
    27 }
    iOS开发者交流群:180080550
  • 相关阅读:
    二叉查找树
    Rust更换Crates源
    Raft共识算法
    Session
    可以编写代码的代码:代码生成的利与弊
    引用和自包含令牌(Reference Tokens and Introspection)
    认证授权-学习笔记1-OAuth 2.0
    spring security原理-学习笔记2-核心组件
    spring security原理-学习笔记1-整体概览
    零拷贝Zero copy-linux and java
  • 原文地址:https://www.cnblogs.com/stevenwuzheng/p/4972897.html
Copyright © 2020-2023  润新知