標籤:java io 檔案 2014 cti div 代碼 line
? ?單例模式算是設計模式中比較簡單的一種吧,設計模式不是只針對某種程式設計語言,在C++, Java, PHP等其他OOP語言也有設計模式,筆者初接觸設計模式是通過《漫談設計模式》瞭解的。這本書中是用java寫的,個人感覺拜讀完這本書以後雖然有不理解的地方但還是收穫蠻大的。上面提到依賴注入,控制翻轉的時候,沒大看懂,當學習到Strut,Spring, Hibernate的東西的時候才略懂略懂。不過在23種設計模式裡面單例模式還是算比較好理解的, 那麼在OC中又是怎麼來表示單例模式的呢?下面會結合著lusashi的代碼,理解一下OC中得單例模式。
? ?首先得瞭解什麼是單例模式,用大白話說,單例模式就是在程式中這個類只對應著一個執行個體,這就是單例模式,單例模式一般用全域靜態對象來實現。下面我們會建立一個產生單例的類SingletonClass,在實現檔案中定義各種方法來實現我們的單例模式。
? ?1.單例模式一般用全域靜態對象來實現,所以我們在SingletonClass.m中定義一個靜態全域變數是少不了的
| 12 |
//定義靜態全域變數static SingletonClass *single = nil; |
? ?2.上面的靜態變數是定義在實現檔案中的所以是私人的,要想擷取該類的執行個體得有個getInstance方法來擷取執行個體,在給靜態變數分配記憶體空間之前首先要判斷是否已經分配過啦,確保單例,如果分配過了就不分配了。
| 123456789 |
//擷取靜態全域對象+(id)getInstance{ //如果沒有產生對象,則為靜態全域變數分配記憶體 if (single == nil) { single = [[SingletonClass alloc] init]; } return single;} |
? ?
? ?3.為了防止使用者通過alloc和new來執行個體化對象,因此我們要對類方法allcoWithZone進行重寫
| 12345678 |
//防止通過alloc或者new來建立新的對象我們要重寫allocWithZone+(id)allocWithZone:(NSZone *)zone{ if (single == nil) { single = [[super allocWithZone:zone] init]; } return single;} |
? ?4.為了防止使用者把單例進行深淺拷貝,我們需要重寫copyWithZone方法和mutableCopyWithZone方法,在重寫方法之前我們的單例類必須遵循協議NSCoping和NSMutableCoping協議
? ?遵循協議代碼如下:
| 123456789 |
@interface SingletonClass : NSObject<NSCopying, NSMutableCopying> //單例中擷取單例對象的方法+(id) getInstance; //單例測試方法-(void) singletonFunction; @end |
? ?重寫copyWithZone方法
| 12345 |
//為了防止通過copy來建立新的執行個體我們要重寫copyWithZone;-(id)copyWithZone:(NSZone *)zone{ return self;} |
? ?重寫mutableCopyWithZone方法
| 1234 |
-(id)mutableCopyWithZone:(NSZone *)zone{ return self;} |
?5.防止使用者把建立的單例dealloc,我們需要重寫retainCount方法
| 12345 |
//重寫retainCount方法,防止被dealloc,返回最大值-(NSUInteger) retainCount{ return NSUIntegerMax;} |
?6. 重寫release,autorelease, retain方法
| 12345678910111213141516 |
//重寫retain,引用計數不變-(id) retain{ return self;} //重寫release-(oneway void) release{} //重寫autorelease-(id) autorelease{ return self;} |
?至此我們的單例模式基本建立完畢,下面開始我們的測試吧;
?在main函數中的代碼如下:
| 12345678910111213141516171819 |
//單例模式的測試SingletonClass *single1 = [SingletonClass getInstance];SingletonClass *single2 = [SingletonClass new];SingletonClass *single3 = [[SingletonClass alloc] init];SingletonClass *single4 = [single1 copy];SingletonClass *single5 = [single1 mutableCopy];SingletonClass *single6 = [single1 retain];[single1 release]; [single1 singletonFunction];NSLog(@"single_retainCount = %lu", single1.retainCount); //輸出地址NSLog(@"getInstance single1_P = %p", single1);NSLog(@"new single2_P = %p", single2);NSLog(@"allo single3_P = %p", single3);NSLog(@"copy single4_P = %p", single4);NSLog(@"mutableCopy single5_P = %p", single5);NSLog(@"retain single6_P = %p", single6); |
? ?運行結果如下:
| 12345678 |
2014-08-07 16:04:44.207 Memory[20664:303] singleton Ps: 我是單例模式中得測試方法!!2014-08-07 16:04:44.207 Memory[20664:303] single_retainCount = 184467440737095516152014-08-07 16:04:44.207 Memory[20664:303] getInstance single1_P = 0x1002046902014-08-07 16:04:44.208 Memory[20664:303] new single2_P = 0x1002046902014-08-07 16:04:44.208 Memory[20664:303] allo single3_P = 0x1002046902014-08-07 16:04:44.208 Memory[20664:303] copy single4_P = 0x1002046902014-08-07 16:04:44.209 Memory[20664:303] mutableCopy single5_P = 0x1002046902014-08-07 16:04:44.209 Memory[20664:303] retain single6_P = 0x100204690 |
? ? ?單例的地址是不變的。