<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                單例在我們開發中是最常用的設計模式,在iOS中也是如此。單例可以保證某個類的實例在程序中是唯一的,便于進行資源和數據的共享。使用的設計原則是單一職責原則。我們來看看在iOS中本身自帶的類或者方法哪些使用了單例的模式: (1)UIAccelerometer類和sharedAccelerometer方法,一般如果方法名中有shared這樣的詞,就可以認為這是一個可以整個應用程序共享的實例變量,一般是使用了單例。 (2)UIApplication類和sharedApplication方法,我們一般使用該方法來創建全局變量。 (3)NSBundle類和mainBundle方法。 (4)NSFileManager類和defaultManager方法。 (5)NSNotificationCenter類和defaultManager方法。其中NSNotificationCenter也實現了觀察者模式。 (6)NSUserDefaults類和defaultUser方法。 示例代碼上傳至:[https://github.com/chenyufeng1991/iOS-Singleton](https://github.com/chenyufeng1991/iOS-Singleton) 。 【單例實現】 (1)新建一個普通的類,假設名字為Singleton. 在Singleton.h中聲明一個類方法,到時候使用該類方法(注意:一定是類方法,而不是實例方法)可以創建該類的唯一的一個實例: ~~~ [objc] view plaincopyprint? #import <Foundation/Foundation.h> @class Singleton; @interface Singleton : NSObject // "+" 表示類的方法,由類調用 +(Singleton *)sharedInstance; @end (2)在Singleton.m中需要實現sharedInstance方法和你其他的業務邏輯: [objc] view plaincopyprint? #import "Singleton.h" // 用static聲明一個類的靜態實例; static Singleton *_sharedInstance = nil; @implementation Singleton /** * 1.使用類方法生成這個類唯一的實例; */ +(Singleton *)sharedInstance{ if (!_sharedInstance) { _sharedInstance =[[self alloc]init]; } return _sharedInstance; } @end ~~~ 注意:一定要聲明一個static的靜態變量。以后創建類的唯一實例就使用sharedInstance方法,而不是使用alloc ,init. (3)我們使用一個簡單的demo來演示一下單例: ~~~ [objc] view plaincopyprint? #import "RootVC.h" #import "Singleton.h" @interface RootVC () @end @implementation RootVC - (void)viewDidLoad { [super viewDidLoad]; [self testSigleTon]; } -(void)testSigleTon { //單例的結果就是,調用類方法,只返回一個共有的對象 /** * single和single2是同一個對象; 因為返回的數據是一個靜態變量,全局唯一; */ Singleton *single = [Singleton sharedInstance]; Singleton *single2 = [Singleton sharedInstance]; if (single == single2) { NSLog(@"single == single2"); } NSLog(@"single地址:%@",single); NSLog(@"single2地址:%@",single2); } @end ~~~ ![http://img.blog.csdn.net/20151224220106085?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center](http://img.blog.csdn.net/20151224220106085?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 可以看到,兩個對象的內存地址是一樣的,表示這兩個對象其實是同一個對象,單例也就實現了。這是單例最普遍也是最簡單的實現方式,在項目中會經常用到,在不涉及多線程的情況下是完全正確的。但是,我們再多想一想,在多線程開發中,這種實現方式是否安全呢?那么應該如何實現。 #### 【單例架構】 在項目開發中,如果我們像上述實現方法一樣,在每個類中都使用這樣寫一個方法來生成單例,會不會顯得很麻煩,很冗余。這樣重復在每個類中重復寫代碼不利于開發與架構,那么我們應該使用什么方法來進行代碼抽取呢?解決方案就是使用類別(Category)。關于Category類別的簡要介紹,請參考《Objective-C——類別(Category)詳解》。具體的實現如下: (1)新建一個Category,作為對NSObject類的擴展。因為NSObject類是大部分iOS類的基類,如果使用Category為NSObject增加額外方法(shareInstance方法),那么所有繼承自NSObject的類都可以使用該方法。我們常用的UIViewController和UIView都是從NSObject繼承的,這樣就會很方便。 需要在NSObject+Singleton.h頭文件中對外暴露一個生成實例的方法,供其他類調用。 ~~~ [objc] view plaincopyprint? #import <Foundation/Foundation.h> @interface NSObject (Singleton) // "+" 表示類的方法,由類調用 + (instancetype)sharedInstance; @end ~~~ (3)在NSObject+Singleton.m中需要實現上述方法,用來生成某一個類的唯一實例。我這里使用字典來存儲某一個類和該類的實例,也就是鍵值對的形式:鍵是類名,值是對象。根據類名去檢索該類的對象是否已經被創建,如果檢索到類名,表示已經被創建,則直接返回對象;如果沒有檢索到類名,則需要創建,創建完成后也存儲到字典中; ~~~ [objc] view plaincopyprint? #import "NSObject+Singleton.h" @implementation NSObject (Singleton) //使用可變字典存儲每個類的單一實例,鍵為類名,值為該類的對象; //聲明為靜態變量,可以保存上次的值; static NSMutableDictionary *instanceDict; id instance; + (instancetype)sharedInstance { @synchronized(self) { //初始化字典; if (instanceDict == nil) { instanceDict = [[NSMutableDictionary alloc] init]; } //獲取類名; NSString *className = NSStringFromClass([self class]); if (className) { //查找字典中該類的對象,使用類名去進行查找,可以確保一個類只被存儲一次; instance = instanceDict[className]; if (instance == nil) { //該類的對象還沒實例化,就進行初始化,并根據鍵值對的形式存儲; instance = [[self.class alloc] init]; [instanceDict setValue:instance forKey:className]; }else{ //該類對象已經存儲在字典中,直接返回instance即可; } }else{ //沒有獲取類名,所以確保sharedInstance是一個類方法,用類進行調用; } return instance; } } @end ~~~ (4)單例的category已經寫完,下面將要進行測試。我這里的測試方法如下:兩個界面之間進行跳轉并返回,使用相同的代碼生成類對象;同時新建一個Person類和StudentModel類來測試,兩個類都分別繼承自NSObject,里面沒有任何實現,只用來創建對象。別忘了導入頭文件#import “NSObject+Singleton.h”. 第一個界面ViewController.m實現如下: ~~~ [objc] view plaincopyprint? #import "ViewController.h" #import "NSObject+Singleton.h" #import "Person.h" #import "StudentModel.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:true]; //使用sharedInstance創建類對象; ViewController *vc1 = [ViewController sharedInstance]; ViewController *vc2 = [ViewController sharedInstance]; NSLog(@"ViewController---vc1地址:%@",vc1); NSLog(@"ViewController---vc2地址:%@",vc2); if (vc1 == vc2) { NSLog(@"ViewController---vc1 == vc2"); } //循環創建5個Person對象,5個對象都相同; for (int i = 0; i < 5; i++) { Person *per1 = [Person sharedInstance]; NSLog(@"ViewController---per1地址:%@",per1); } //使用alloc創建對象,每個對象都是不同的; for (int i = 0; i < 5; i++) { StudentModel *stud = [[StudentModel alloc] init]; NSLog(@"ViewController---stud地址:%@",stud); } } @end ~~~ 第二個界面SecondViewController.m實現如下: ~~~ [objc] view plaincopyprint? #import "SecondViewController.h" #import "NSObject+Singleton.h" #import "Person.h" #import "StudentModel.h" #import "ViewController.h" @interface SecondViewController () @end @implementation SecondViewController /** * 在另一個界面中做同樣的測試; */ - (void)viewDidLoad { [super viewDidLoad]; } - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; SecondViewController *secondVc1 = [SecondViewController sharedInstance]; SecondViewController *secondVc2 = [SecondViewController sharedInstance]; NSLog(@"SecondViewController---secondVc1地址:%@",secondVc1); NSLog(@"SecondViewController---secondVc2地址:%@",secondVc2); if (secondVc1 == secondVc2) { NSLog(@"SecondViewController---secondVc1 == secondVc2"); } for (int i = 0; i < 5; i++) { Person *per1 = [Person sharedInstance]; NSLog(@"SecondViewController---per1地址:%@",per1); } for (int i = 0; i < 5; i++) { StudentModel *stud = [[StudentModel alloc] init]; NSLog(@"SecondViewController---stud地址:%@",stud); } } /** * 返回上一界面,再次生成對象查看; * * @param sender <#sender description#> */ - (IBAction)back:(id)sender { [self dismissViewControllerAnimated:true completion:nil]; } @end ~~~ 下面分別是三個步驟打印log:啟動第一個界面、跳轉到第二個界面、返回第一個界面。 啟動第一個界面的輸出: ![http://img.blog.csdn.net/20151225141656534?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center](http://img.blog.csdn.net/20151225141656534?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 跳轉到第二個界面的輸出: ![http://img.blog.csdn.net/20151225141815787?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center](http://img.blog.csdn.net/20151225141815787?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 再次返回到第一個界面的輸出: ![http://img.blog.csdn.net/20151225141938019?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center](http://img.blog.csdn.net/20151225141938019?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) ### 總結 通過以上打印輸出,使用sharedInstance創建單例后,無論在哪一個界面,每個類的對象是唯一的。而使用alloc創建的對象往往都是不同的。通過以上的設計,就不需要在每一個類中都去實現sharedInstance方法了。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看