zoukankan      html  css  js  c++  java
  • 单例模式——使用GCD实现单例模式 & 非ARC单例模式 &使用GCD和线程锁实现单例模式-b

    1.单利模式概述

     链接:  iOS开发懒汉模式&恶寒模式

    2.使用GCD实现单利模式

    2.1新建一个project,然后新建一个HMDataTool类展示GCD实现单例模式

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #import <Foundation/Foundation.h>  
    2.   
    3. @interface HMDataTool : NSObject  
    4. + (instancetype)sharedDataTool;  
    5. @end  
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #import "HMDataTool.h"  
    2.   
    3. @implementation HMDataTool  
    4. // 用来保存唯一的单例对象  
    5. static id _instace;  
    6.   
    7. + (id)allocWithZone:(struct _NSZone *)zone  
    8. {  
    9.     static dispatch_once_t onceToken;  
    10.     dispatch_once(&onceToken, ^{   //onceToken是GCD用来记录是否执行过 ,如果已经执行过就不再执行(保证执行一次)  
    11.         _instace = [super allocWithZone:zone];  
    12.     });  
    13.     return _instace;  
    14. }  
    15.   
    16. + (instancetype)sharedDataTool  
    17. {  
    18.     static dispatch_once_t onceToken;  
    19.     dispatch_once(&onceToken, ^{  
    20.         _instace = [[self alloc] init];  
    21.     });  
    22.     return _instace;  
    23. }  
    24.   
    25. - (id)copyWithZone:(NSZone *)zone  
    26. {  
    27.     return _instace;  
    28. }  
    29.   
    30. @end  
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. #import "htingViewController.h"  
    2. #import"HMDataTool.h"  
    3. @interface htingViewController ()  
    4.   
    5. @end  
    6.   
    7. @implementation htingViewController  
    8.   
    9. - (void)viewDidLoad  
    10. {  
    11.     [super viewDidLoad];  
    12.     // Do any additional setup after loading the view, typically from a nib.  
    13.       
    14.         HMDataTool *tool1 = [HMDataTool sharedDataTool];  
    15.         HMDataTool *tool2 = [HMDataTool sharedDataTool];  
    16.         HMDataTool *tool3 = [[HMDataTool alloc] init];  
    17.         HMDataTool *tool4 = [[HMDataTool alloc] init];  
    18.       
    19.         NSLog(@"%@ %@ %@ %@", tool1, tool2, tool3, tool4);  
    20. }  
    21.   
    22.   
    23.   
    24. @end  


    打印结果

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. 使用GCD实现单利模式[2334:607] <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0>  

    3.非ARC实现单例模式

    3.1非ARC内存管理模式下对象必须手动释放,为了防止那个唯一的单例对象被释放掉,则只需要重写下面的几个方法即可

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. - (oneway void)release { }  
    2. - (id)retain { return self; }  
    3. - (NSUInteger)retainCount { return 1;}  
    4. - (id)autorelease { return self;}  

    3.2通过新建一个HMDataTool类来演示非ARC单例模式

     
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //  HMDataTool.h  
    2.   
    3.   
    4. #import <Foundation/Foundation.h>  
    5.   
    6. @interface HMDataTool : NSObject  
    7. + (instancetype)sharedDataTool;  
    8. @end  
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //  
    2. //  HMDataTool.m  
    3. //  03-单例模式-Singleton(掌握)  
    4. //  
    5. //  Created by apple on 14-9-16.  
    6. //  Copyright (c) 2014年 heima. All rights reserved.  
    7. //  
    8.   
    9. #import "HMDataTool.h"  
    10.   
    11. @implementation HMDataTool  
    12. // 用来保存唯一的单例对象  
    13. static id _instace;  
    14.   
    15. + (id)allocWithZone:(struct _NSZone *)zone  
    16. {  
    17.     static dispatch_once_t onceToken;  
    18.     dispatch_once(&onceToken, ^{  
    19.         _instace = [super allocWithZone:zone];  
    20.     });  
    21.     return _instace;  
    22. }  
    23.   
    24. + (instancetype)sharedDataTool  
    25. {  
    26.     static dispatch_once_t onceToken;  
    27.     dispatch_once(&onceToken, ^{  
    28.         _instace = [[self alloc] init];  
    29.     });  
    30.     return _instace;  
    31. }  
    32.   
    33. - (id)copyWithZone:(NSZone *)zone  
    34. {  
    35.     return _instace;  
    36. }  
    37. /** 
    38.  *  重写下面几个关于引用计数器的方法就可以防止修改引用计数器的值, 
    39.     这样就可以这个对象永远停留在内存中(因为这几个方法都是空的,所以尽管怎么调用,都没有作用) 
    40.  * 
    41.  *  @return <#return value description#> 
    42.  */  
    43.   
    44. - (oneway void)release { }  
    45. - (id)retain { return self; }  
    46. - (NSUInteger)retainCount { return 1;}  
    47. - (id)autorelease { return self;}  
    48.   
    49. @end  

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //  
    2. //  HMViewController.h  
    3.   
    4.   
    5. #import <UIKit/UIKit.h>  
    6.   
    7. @interface HMViewController : UIViewController  
    8.   
    9. @end  

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //  
    2. //  HMViewController.m  
    3.   
    4.   
    5.   
    6. #import "HMViewController.h"  
    7. #import "HMDataTool.h"  
    8.   
    9. @interface HMViewController ()  
    10.   
    11. @end  
    12.   
    13. @implementation HMViewController  
    14.   
    15. - (void)viewDidLoad  
    16. {  
    17.     [super viewDidLoad];  
    18.       
    19.     HMDataTool *tool1 = [[HMDataTool alloc] init];  
    20.     HMDataTool *tool2 = [[HMDataTool alloc] init];  
    21.     HMDataTool *tool3 = [HMDataTool sharedDataTool];  
    22.     HMDataTool *tool4 = [HMDataTool sharedDataTool];  
    23.     /** 
    24.      *  重写了下面几个方法之后,则随便释放N次都没有用了 
    25.      - (oneway void)release { } 
    26.      - (id)retain { return self; } 
    27.      - (NSUInteger)retainCount { return 1;} 
    28.      - (id)autorelease { return self;} 
    29.       
    30.      */  
    31.       [tool4 autorelease];  
    32.       [tool4 autorelease];  
    33.       [tool4 autorelease];  
    34.       [tool4 autorelease];  
    35.       [tool4 autorelease];  
    36.       
    37.     NSLog(@"%@ %@ %@ %@", tool1, tool2, tool3, tool4);  
    38. }<pre name="code" class="objc">+(loginModel *)sharedloginModel  
    39. {  
    40.     static loginModel *loginmodle = nil;  
    41.     @synchronized(self)  
    42.     {  
    43.         if (loginmodle == nil) {  
    44.             loginmodle = [[loginModel alloc] init];  
    45.         }  
    46.     }  
    47.       
    48.     return loginmodle;  
    49.       
    50. }  

    @end
    
    运行结果

    单例模式-ARC(掌握)[2592:607] <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600>

     

    4.线程锁和GCD实现单例模式

    4.1线程锁和GCD实现单粒模式

    线程锁实现单粒
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. +(Muser *)sharedMuser  
    2. {  
    3.     staticstatic *user = nil;  
    4.     @synchronized(self)  
    5.     {  
    6.         if (user == nil) {  
    7.             user = [[Muser alloc] init];  
    8.         }  
    9.     }  
    10.       
    11.     return user;  
    12.       
    13. }  
    GCD实现单粒
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. +(<span style="font-family: Arial, Helvetica, sans-serif;">sharedsegMentTitles</span><span style="font-family: Arial, Helvetica, sans-serif;"> *</span><span style="font-family: Arial, Helvetica, sans-serif;">)sharedsegMentTitles</span>  
    2. {  
    3.     static SwitchMenuViewModel * segTitles = nil;  
    4.     static dispatch_once_t once;  
    5.     dispatch_once(&once,^{  
    6.    if (segTitles == nil) {  
    7.       segTitles = [[SwitchMenuViewModel alloc]init];  
    8.         }  
    9.     });  
    10.     return segTitles;  
    11. }  



    4.2为什么使用宏?

     
    假设一个项目中有多个类需要单例,则需要每个类都实现一遍单例,这样很繁琐,因此可以采用定义宏的方式,写一个单例文件添加到项目中然后在项目的Prefix.pch文件中得这个地方包含进去即可
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. // .h文件 shared##name 是让前面HMSingletonH(name) 接收到的参数拼接起来  
    2. #define HMSingletonH(name) + (instancetype)shared##name;  
    3.   
    4. // .m文件  如果是ARC  
    5. #if __has_feature(objc_arc)  
    6.   
    7.     #define HMSingletonM(name)   
    8.     static id _instace;   
    9.    
    10.     + (id)allocWithZone:(struct _NSZone *)zone   
    11.     {   
    12.         static dispatch_once_t onceToken;   
    13.         dispatch_once(&onceToken, ^{   
    14.             _instace = [super allocWithZone:zone];   
    15.         });   
    16.         return _instace;   
    17.     }   
    18.    
    19.     + (instancetype)shared##name   
    20.     {   
    21.         static dispatch_once_t onceToken;   
    22.         dispatch_once(&onceToken, ^{   
    23.             _instace = [[self alloc] init];   
    24.         });   
    25.         return _instace;   
    26.     }   
    27.    
    28.     - (id)copyWithZone:(NSZone *)zone   
    29.     {   
    30.         return _instace;   
    31.     }  
    32. //如果是非ARC  
    33. #else  
    34.   
    35.     #define HMSingletonM(name)   
    36.     static id _instace;   
    37.    
    38.     + (id)allocWithZone:(struct _NSZone *)zone   
    39.     {   
    40.         static dispatch_once_t onceToken;   
    41.         dispatch_once(&onceToken, ^{   
    42.             _instace = [super allocWithZone:zone];   
    43.         });   
    44.         return _instace;   
    45.     }   
    46.    
    47.     + (instancetype)shared##name   
    48.     {   
    49.         static dispatch_once_t onceToken;   
    50.         dispatch_once(&onceToken, ^{   
    51.             _instace = [[self alloc] init];   
    52.         });   
    53.         return _instace;   
    54.     }   
    55.    
    56.     - (id)copyWithZone:(NSZone *)zone   
    57.     {   
    58.         return _instace;   
    59.     }   
    60.    
    61.     - (oneway void)release { }   
    62.     - (id)retain { return self; }   
    63.     - (NSUInteger)retainCount { return 1;}   
    64.     - (id)autorelease { return self;}  
    65.   
    66. #endif  
    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. //  
    2. //  HMViewController.m  
    3. //    
    4. #import "HMViewController.h"  
    5. #import "HMMusicTool.h"  
    6. #import "HMMovieTool.h"  
    7. #import "HMDataTool.h"  
    8.   
    9. #import "HMPerson.h"  
    10.   
    11. @interface HMViewController ()  
    12.   
    13. @end  
    14.   
    15. @implementation HMViewController  
    16.   
    17. - (void)viewDidLoad  
    18. {  
    19.     [super viewDidLoad];  
    20.       
    21. //    HMMusicTool *tool1 = [HMMusicTool sharedMusicTool];  
    22. //    HMMusicTool *tool2 = [HMMusicTool sharedMusicTool];  
    23. //  
    24. //    HMMovieTool *tool3 = [HMMovieTool sharedMovieTool];  
    25. //    HMMovieTool *tool4 = [HMMovieTool sharedMovieTool];  
    26. //      
    27. //    HMDataTool *tool5 = [HMDataTool sharedDataTool];  
    28. //    HMDataTool *tool6 = [HMDataTool sharedDataTool];  
    29. //  
    30. //    NSLog(@"%@ %@", tool5, tool6);  
    31.       
    32.     HMPerson *p = [[HMPerson alloc] init];  
    33.       
    34. #if __has_feature(objc_arc)  
    35.     // 编译器是ARC环境  
    36. #else  
    37.     // 编译器是MRC环境  
    38.     [p release];  
    39. #endif  
    40. }  
    41.   
    42. @end  



     
    为什么使用宏?
    这样可以方便项目中的其它单例的创建,只需要在项目中包含即可共用,而不必要再次用代码为每一个单例对象实现单例
  • 相关阅读:
    OSX中zsh新增环境变量
    新的开始 春光明媚
    tmux
    继承
    6
    Object类
    网页收藏
    画王八
    ES6 语法之import export
    ES6 语法 之 destructuring
  • 原文地址:https://www.cnblogs.com/isItOk/p/5598483.html
Copyright © 2011-2022 走看看