国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

ios開發(fā)之單例模式

2019-11-14 20:08:46
字體:
供稿:網(wǎng)友

在iOS開發(fā)中,有很多地方都選擇使用單例模式。有很多時候必須要創(chuàng)建一個對象,并且不能創(chuàng)建多個,用單例就為了防止創(chuàng)建多個對象。單例模式的意思就是某一個類有且只有一個實例。單例模式確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。這個類稱為單例類。

一、單例模式的三要點:

1. 該類有且只有一個實例;

2. 該類必須能夠自行創(chuàng)建這個實例;

3. 該類必須能夠自行向整個系統(tǒng)提供這個實例。

二、單例模式的優(yōu)點與缺點:

1. 內(nèi)存占用與運行時間

   對比使用單例模式和非單例模式的例子,在內(nèi)存占用與運行時間存在以下差距:

   (1) 單例模式:單例模式每次獲取實例時都會先進行判斷,看該實例是否存在——如果存在,則返回;否則,則創(chuàng)建實例。因此,會浪費一些判斷的時間。但是,如果一直沒有人使用這個實例的話,那么就不會創(chuàng)建實例,節(jié)約了內(nèi)存空間。

   (2) 非單例模式:當類加載的時候就會創(chuàng)建類的實例,不管你是否使用它。然后當每次調(diào)用的時候就不需要判斷該實例是否存在了,節(jié)省了運行的時間。但是如果該實例沒有使用的話,就浪費了內(nèi)存。

  (3)實例控制:Singleton 會阻止其他對象實例化其自己的 Singleton 對象的副本,從而確保所有對象都訪問唯一實例。

   靈活性:因為類控制了實例化過程,所以類可以更加靈活修改實例化過程。

2. 線程的安全性

    (1) 從線程的安全性上來講,不加同步的單例模式是不安全的。比如,有兩個線程,一個是線程A,另外一個是線程B,如果它們同時調(diào)用某一個方法,那就可能會導致并發(fā)問題。在這種情況下,會創(chuàng)建出兩個實例來,也就是單例的控制在并發(fā)情況下失效了。

    (2) 非單例模式是線程安全的,因為程序保證只加載一次,在加載的時候不會發(fā)生并發(fā)情況。

    (3) 單例模式如果要實現(xiàn)線程安全,只需要加上synchronized即可。但是這樣一來,就會減低整個程序的訪問速度,而且每次都要判斷,比較麻煩。

    (4) 雙重檢查加鎖:為了解決(3)的繁瑣問題,可以使用“雙重檢查加鎖”的方式來實現(xiàn),這樣,就可以既實現(xiàn)線程安全,又能使得程序性能不受太大的影響。

         (4.1) 雙重檢查加鎖機制——并不是每次進入要調(diào)用的方法都需要同步,而是先不同步,等進入了方法之后,先檢查實例是否存在,如果不存在才進入下面的同步塊,這是第一重檢查。當進入同步塊后,再次檢查實例是否存在,如果不存在,就在同步的情況下創(chuàng)建一個實例,這是第二重檢查。這樣一來,就只需要同步一次,從而減少了多次在同步情況下進行判斷所浪費的時間。

         (4.2) 雙重檢查加鎖機制的實現(xiàn),會使用一個關鍵字volatile。它的意思是:被volatile修飾的變量的值,將不會被本地線程緩存,所有對該變量的讀寫都是直接操作共享內(nèi)存的,從而確保了多個線程能正確的處理該變量。這種實現(xiàn)方式既可以實現(xiàn)線程安全地創(chuàng)建實例,而又不會對性能造成太大的影響。它只是在第一次創(chuàng)建實例的時候同步,以后就不需要同步了,從而加快了運行速度。

3. 單例模式會阻止其它對象實例化其自己的對象的副本,從而確保所有對象都訪問唯一實例。

4. 因為單例模式的類控制了實例化的過程,所以類可以更加靈活修改實例化過程。

三、iOS中的單例模式

1. 基本步驟:

   (1) 為單例對象創(chuàng)建一個靜態(tài)實例,可以寫成全局的,也可以在類方法里面實現(xiàn),并初始化為nil;

   (2) 實現(xiàn)一個實例構造方法,檢查上面聲明的靜態(tài)實例是否為nil,如果是,則創(chuàng)建并返回一個本類的實例;

   (3) 重寫allocWithZone方法,用來保證其他人直接使用alloc和init試圖獲得一個新實力的時候不產(chǎn)生一個新實例;

   (4) 適當實現(xiàn)allocWitheZone,copyWithZone,release和autorelease。

//第一步:靜態(tài)實例,并初始化。
static SurveyRunTimeData *sharedObj = nil;
@implementation SurveyRunTimeData

//第二步:實例構造檢查靜態(tài)實例是否為nil
{
+ (SurveyRunTimeData*) sharedInstance 
    @synchronized (self)
    {
        if (sharedObj == nil)
        {
            [[self alloc] init];
        }
    }
    return sharedObj;
}

//第三步:重寫allocWithZone方法
+ (id) allocWithZone:(NSZone *)zone
{
    @synchronized (self) {
        if (sharedObj == nil) {
            sharedObj = [super allocWithZone:zone];
            return sharedObj;
        }
    }
    return nil;
}
//第四步
- (id) copyWithZone:(NSZone *)zone
{
    return self;
}

//一下方法再Xcode5以上,已經(jīng)不需要!大家根據(jù)事情情況自行判斷!
- (id) retain
{
    return self;
}

- (unsigned) retainCount
{
    return UINT_MAX;
}

- (oneway void) release
{
    
}

- (id) autorelease
{
    return self;
}

- (id)init
{
    @synchronized(self) {
        [super init];//往往放一些要初始化的變量.
        return self;
    }
}

@end

+(id)allocWithZone:(NSZone *)zone{
        @synchronized(self){
                if (shareRootViewController == nil) {
                   shareRootViewController = [super allocWithZone:zone];
                    return  shareRootViewController;
                }
            }
        return nil;
}

NSZone: 簡單來說可以把它想象成一個內(nèi)存池,alloc或者dealloc這些操作都是在這個內(nèi)存池中操作的,cocoa總是會分配一個默認的nsZone,任何 默認內(nèi)存操作都是在這個zone上進行的,使用默認zone存在缺陷,因為他是全局范圍的,頻繁使用會導致內(nèi)存的碎片化,尤其是大量的alloc和 dealloc的時候,性能上會受到一定影響。因為你完全可以自己生成一個zone并將alloc,copy這些限制在這個zone中。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 纳雍县| 二手房| 龙井市| 南投市| 静乐县| 徐州市| 崇明县| 涞水县| 迁安市| 龙山县| 宁蒗| 长沙县| 南投县| 和平县| 屏边| 同仁县| 宝丰县| 泸州市| 梓潼县| 花莲市| 百色市| 谢通门县| 元氏县| 阿克| 卓尼县| 万宁市| 屯留县| 临泽县| 莱州市| 镇沅| 东港市| 古丈县| 铜川市| 丰宁| 广平县| 泰宁县| 建瓯市| 同仁县| 太湖县| 深水埗区| 丹棱县|