日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

iOS设计模式 ——单例模式详解以及严格单例模式注意点

發布時間:2023/12/13 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS设计模式 ——单例模式详解以及严格单例模式注意点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、我們常用的單例有哪些?

  • [[UIApplication sharedApplication] statusBarStyle];//系統中的單例模式,通過它獲取到狀態欄的style

  • [NSNotificationCenter defaultCenter] addObserver:<#(nonnull id)#> selector:<#(nonnull SEL)#> name:<#(nullable NSString *)#> object:<#(nullable id)#>];//defaultCenter從控制中心類中獲取到了單例的實例
  • [NSUserDefaults standardUserDefaults] setObject:<#(nullable id)#> forKey:<#(nonnull NSString *)#>];
  • [NSFileManager defaultManager];
  • 從這些常用的單例可以發現,通過這些常用的單例方法來獲取到這個類的唯一實例,再在這個實例的基礎上進行相關的操作、作業。

    二、單例模式基本原理

    單例模式,一般用來管理某些資源的,用來管理某個對象,他這個對象持有了某些核心資源,這個資源可以全局共享。大部分情況我們使用單例模式就是為了共享信息 ,一般作為管理中心。

    缺點是因為他共享了信息,就破壞了設計模式中的最少知識原則,產生了耦合,破壞了封裝性,。但是在解決問題的過程中,這種不好的地方也是可以忽略的。


    下面我們來自己寫一個單例的例子,詳細的講一下對單例的理解。創建一個UserInfoManagerCenter的類

    仿照系統的單例形式自己寫這個類方法。

  • #import <Foundation/Foundation.h>
  • @interface UserInfoManagerCenter : NSObject
  • @property (nonatomic ,strong) NSString *name;
  • @property (nonatomic ,strong) NSString *age;
  • + (instancetype)managerCenter;
  • @end
  • UserInfoManagerCenter.m中實現這個方法

  • #import "UserInfoManagerCenter.h"
  • @implementation UserInfoManagerCenter
  • /**
  • * ?常規做法
  • */
  • +(instancetype)managerCenter
  • {
  • ? ?static UserInfoManagerCenter *center = nil;//靜態變量持有這個對象
  • ? ?if (center == nil) {
  • ? ? ? ?center = [[UserInfoManagerCenter alloc]init];
  • ? ?}
  • ? ?return center;
  • }
  • @end
  • 但是這種方法并不好,當多個地方調用這個方法時,會造成同時都進入到alloc init。

    因此,使用第二種方法

  • #import "UserInfoManagerCenter.h"
  • @implementation UserInfoManagerCenter
  • /**
  • * ?第二種方案,用dispatch_once來解決競爭問題
  • */
  • +(instancetype)managerCenter
  • {
  • ? ?static UserInfoManagerCenter *center = nil;
  • ? ?static dispatch_once_t onceToken;
  • ? ?dispatch_once(&onceToken, ^{
  • ? ? ? ?center = [[UserInfoManagerCenter alloc]init];
  • ? ?});
  • ? ?return center;
  • }
  • @end
  • 當然還有第三種方法 ? ?--- ??initialize的作用,同一個類初始化時只會調用一次。

  • #import "UserInfoManagerCenter.h"
  • static UserInfoManagerCenter *center = nil;
  • @implementation UserInfoManagerCenter
  • /**
  • * 第三種方法,每個類調用任意方法時都會提前調用的這個initialize方法,initialize的作用,同一個類初始化時只會調用一次。所以說我們將單例寫在這個地方也是沒有問題的,但是不推薦
  • */
  • +(void)initialize
  • {
  • if (self == [UserInfoManagerCenter class]) {
  • center = [[UserInfoManagerCenter alloc]init];
  • }
  • }
  • +(instancetype)managerCenter
  • {
  • return center;
  • }
  • @end

  • 讓我們來驗證下,然后在AppDelegate里賦值

  • #import "AppDelegate.h"
  • #import "UserInfoManagerCenter.h"
  • @interface AppDelegate ()
  • @end
  • @implementation AppDelegate
  • - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  • UserInfoManagerCenter *center = [UserInfoManagerCenter managerCenter];
  • center.name = @"YUSIR";
  • return YES;
  • }
  • 在ViewController的viewDidLoad里取出值查看結果

  • #import "ViewController.h"
  • #import "UserInfoManagerCenter.h"
  • @interface ViewController ()
  • @end
  • @implementation ViewController
  • - (void)viewDidLoad {
  • [super viewDidLoad];
  • UserInfoManagerCenter * center = [UserInfoManagerCenter managerCenter];
  • NSLog(@"name:%@",center.name);
  • }
  • 三種方法結果能打印出來,單例實現了資源共享

    三、嚴格單例模式的注意點

    下面來簡單談談嚴格的單例模式,有三個問題可能需要注意一下:

    1.如何防止繼承;

    2.如何確保實例對象只出現一個;

    3.防止實例對象被釋放掉;

    第一個問題,防止繼承

  • +(instancetype)managerCenter
  • {
  • static UserInfoManagerCenter *center = nil;
  • static dispatch_once_t onceToken;
  • dispatch_once(&onceToken, ^{
  • center = [[UserInfoManagerCenter alloc]init];
  • });
  • //防止子類重載調用使用
  • NSString *classString = NSStringFromClass([self class]);//獲取當前類的名字
  • if ([classString isEqualToString:@"UserInfoManagerCenter"] == NO) {
  • NSParameterAssert(nil); //填nil會導致程序崩潰
  • }
  • return center;
  • }
  • 創建一個子類繼承自UserInfoManagerCenter,調用managerCenter會直接崩潰,比較簡單這里就不截圖了

    第二個問題,如何確保實例對象只出現一個。除了類方法之類還有init方法,只能重寫他的init方法,來實現init方法失效

  • static UserInfoManagerCenter *center = nil;
  • @implementation UserInfoManagerCenter
  • +(instancetype)managerCenter
  • {
  • static dispatch_once_t onceToken;
  • dispatch_once(&onceToken, ^{
  • center = (UserInfoManagerCenter *)@"UserInfoManagerCenter";
  • center = [[UserInfoManagerCenter alloc]init];
  • });
  • //防止子類重載調用使用
  • NSString *classString = NSStringFromClass([self class]);//獲取當前類的名字
  • if ([classString isEqualToString:@"UserInfoManagerCenter"] == NO) {
  • NSParameterAssert(nil); //填nil會導致程序崩潰
  • }
  • return center;
  • }
  • - (instancetype)init {
  • NSString *string = (NSString *)center;
  • if ([string isKindOfClass:[NSString class]]== YES && [string isEqualToString:@"UserInfoManagerCenter"]) {
  • self = [super init];
  • if (self) {
  • //防止子類重載調用使用
  • NSString *classString = NSStringFromClass([self class]);//獲取當前類的名字
  • if ([classString isEqualToString:@"UserInfoManagerCenter"] == NO) {
  • NSParameterAssert(nil); //填nil會導致程序崩潰
  • }
  • }
  • return self;
  • }else {
  • return nil;
  • }
  • }

  • 第三個,由于現在是項目是ARC開發的,是引用計數管理的。無法重載release,可以跳過這個問題。

    當然嚴格的單例模式,只要注意避免類似情況發生,就可以不用過多考慮這些負擔了。
    






    總結

    以上是生活随笔為你收集整理的iOS设计模式 ——单例模式详解以及严格单例模式注意点的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。