標籤:
1.原型
原型設計模式所謂原型設計模式,其實就是對象複製,這個特性在所有語言基本上都是存在的。
我們知道在OC中,對象賦值其實是對對象的引用複製,其實就是相當於C語言中的指標。建立了一個新的變數,但是還是指向的同一塊記憶體位址。
所以一旦一個引用改變了該對象的屬性,那麼其他指向該對象的引用全部都會發生變化。
有時候我們並不像要這樣做,我們希望重新建立一個和賦值對象一模一樣的一個對象。比如我們寫遊戲的時候建立了一個enemy對象並對其複雜的行走路徑進行了自訂,此時我們想要在建立一個。但是再次建立時,所有建立過程都要重新再寫一遍,這樣非常的不方便。再比如說我們建立了一個樹形結構,如果想重新一個同樣的對象,代價會非常大,此時我們就需要用到原型設計模式來對對象進行複製。
何時使用
1.需要建立的對象應獨立於其類型與建立方式。
也就是說我們想要的對象並不能夠直接通過初始化函數來建立出來,其建立過程不具有普遍性且複雜。
2.要執行個體化類是在運行時決定的。
在編寫代碼的時候並不知道哪種對象會被建立出來,其內部的結構如何複雜(例如:複雜程度取決於使用者的操作)
3.不想要與產品層次相對應的工廠層次
不通過Factory 方法或者抽象工廠來控制產品的建立過程,想要直接複製對象
4.不同類的執行個體間的差異僅是狀態的若干組合。因此複製相應數量的原型比手工執行個體化更加方便
5.類不容易建立,比如每個組件可把其他組件作為子節點的組合對象。複製已有的組合對象並對副本進行修改會更加容易。
如果內部結構複雜,不容易重現。
以下兩種常見的使用情境
1.有很多相關的類,其行為略有不同,而且主要差異在於內部屬性,如名稱、映像等;
2.需要使用組合(樹形)對象作為其他東西的基礎,例如,使用組合對象作為組件來構建另一個組合對象。
淺複製與深複製
淺複製:只複製指標而不對內部對象進行複製。
深複製:即複製指標,又為內部對象進行單獨複製重新開闢記憶體空間。
OC對象複製
OC的深複製需要實現NSCopying協議及其方法
-(id)copyWithZone:(NSZone *)zone。
NSObject有一個執行個體方法是(id)copy。
預設copy方法調用[self copy withZone:nil]
對於採納了NSCopying協議的子類,需要實現這個方法,否則將引發異常。iOS中,這個方法保持新的副本對象,然後將其返回。
多數情況下深複製並不複雜,思路就是複製必須的成員變數與資源,傳給此類的新執行個體,然後返回這個新類型。
demo
Prototype是實現NSCopying協議,並且實現了(id)copyWithZone:(NSZone *)zone方法的類。
1 2 Prototype *type1 = [Prototype new]; 3 type1.name = @"123"; 4 Prototype *type2 = type1; 5 if(type1.name == type2.name) 6 NSLog(@"%p",&type1); 7 Prototype *type3 = [type1 copy]; 8 if(type1.name == type3.name) 9 NSLog(@"%p",&type3);10 type1.name [email protected]"456";11 NSLog(@"%@ %@",type2.name , type3.name);12 13 /*14 2015-07-19 21:15:13.618 Prototype[31679:8185916] 0x7fff5fbff7e815 2015-07-19 21:15:13.619 Prototype[31679:8185916] 0x7fff5fbff7d816 2015-07-19 21:15:13.619 Prototype[31679:8185916] 456 12317 */
可以看出來,type1屬性變化時,淺複製的type2也跟著變,但是type3還是保留原值證明其為深複製。
Objective-C設計模式——原型Prototype(對象建立)