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

首頁 > 學院 > 開發設計 > 正文

iOS開發之單例模式

2019-11-14 19:18:39
字體:
來源:轉載
供稿:網友

iOS開發之單例模式

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

一、單例模式的三要點:

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

  2. 該類必須能夠自行創建這個實例;

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

 

二、單例模式的優點與缺點:

 1. 內存占用與運行時間

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

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

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

 2. 線程的安全性

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

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

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

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

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

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

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

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

 

三、iOS中的單例模式

 1. 基本步驟:

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

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

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

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

 

 1 下面以ImageStore為例子來簡述一下如何創建一個單例模式: 2  3 在ImageStore.h文件中,編寫代碼如下: 4 #import <Foundation/Foundation.h> 5 @interface ImageStore : NSObject 6 { 7     NSMutableDictionary *dictionary; 8 } 9 + (ImageStore*)defaultImageStore;10 - (void)setImage : (UIImage*)image forKey : (NSString*)string;11 - (UIImage*)imageForKey : (NSString*)string;12 - (void)deleteImageForKey : (NSString*)string;13 @end14 15 在ImageStore.m文件中,編寫代碼如下:16 #import "ImageStore.h"17 static ImageStore *defaultImageStore = nil;18 @implementation ImageStore19 //防止創建另一個該類型的實例20 + (id)allocWithZone:(NSZone *)zone21 {22     return [self defaultImageStore];23 }24 + (ImageStore*)defaultImageStore25 {26     if(!defaultImageStore)27     {28         //創建一個單例29         defaultImageStore = [[super allocWithZone:NULL]init];30     }31                 32     return defaultImageStore;33 }34 - (id)init35 {36     if(defaultImageStore)37     {38         return defaultImageStore;39     }40                 41     self = [super init];42                 43     if(self)44     {45         dictionary = [[NSMutableDictionary alloc]init];46     }47                 48     return self;49 }50 - (void)setImage:(UIImage *)image forKey:(NSString *)string51 {52     [dictionary setObject:image forKey:string];53 }54 - (UIImage*)imageForKey:(NSString *)string55 {56     return [dictionary objectForKey:string];57 }58 - (void)deleteImageForKey:(NSString *)string59 {60     if(!string)61     {62         return;63     }64                 65     [dictionary removeObjectForKey:string];66 }67 @end

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新邵县| 锦州市| 枝江市| 黄山市| 哈巴河县| 延川县| 纳雍县| 拜泉县| 霍城县| 钦州市| 铜川市| 乌兰浩特市| 苍溪县| 礼泉县| 嵊州市| 岳阳市| 北宁市| 当涂县| 抚远县| 曲阳县| 宜章县| 凤台县| 江门市| 漳浦县| 甘肃省| 翁牛特旗| 墨江| 蓬莱市| 弥渡县| 射阳县| 杭锦旗| 莱阳市| 新河县| 山西省| 榆树市| 镇坪县| 抚远县| 涡阳县| 湖南省| 稷山县| 泗洪县|