舉例講解設(shè)計(jì)模式中的原型模式在iOS應(yīng)用開發(fā)中的作用
1 前言
在許多面向?qū)ο蟮膽?yīng)用程序中,有些對象的創(chuàng)建代價過于大或者過于復(fù)雜。要是可以重建相同的對象并作輕微的改動,事情會容易許多。我們可以通過輕微的改動重用已有的對象,以適應(yīng)程序中的特定情況。今天我們就來學(xué)習(xí)一下該模式。
2 詳述
2.1 定義
應(yīng)用于“復(fù)制”操作的模式成為原型(Prototype)模式。復(fù)制(cloning)指用同一模具生產(chǎn)一系列的產(chǎn)品。模具所基于的物品稱為原型。盡管產(chǎn)品是用同一模具復(fù)制的,但是某些屬性,如顏色與尺寸,可以稍有不同,但是他們還是屬于同一類。
2.2 何時是用原型模式
(1)需要創(chuàng)建的對象應(yīng)獨(dú)立于其類型與創(chuàng)建方式。
(2)要實(shí)例化的類是在運(yùn)行時決定的。
(3)不想要與產(chǎn)品層次相對應(yīng)的工廠層次。
(4)不同類的實(shí)例間的差異僅是狀態(tài)的若干組合。因此復(fù)制相應(yīng)數(shù)量的原型比手工實(shí)例化更加方便。
(5)類不容易創(chuàng)建,比如每個組件可以把其他組件作為子節(jié)點(diǎn)的組合對象。復(fù)制已有的組合對象并對副本進(jìn)行修改會更加容易。
此模式的最低限度是生成對象的真實(shí)副本,以用作同一環(huán)境下其他相關(guān)事物的基礎(chǔ)(原型)。
2.3 淺復(fù)制與深復(fù)制
深復(fù)制就是開辟新內(nèi)存實(shí)現(xiàn)真正的內(nèi)存復(fù)制, 淺復(fù)制, 只復(fù)制指針, 堆內(nèi)存不變. 在我們設(shè)計(jì)系統(tǒng)時, 有時一些對象需要根據(jù)用戶操作完成拷貝備份等操作, 這時候, 如果再去按照原來的方法初始化一遍對象就會帶來一些不便和問題:
(1)該對象的某些屬性是在用戶操作過程中產(chǎn)生的, 不能夠僅憑一個initXXX方法賦值;
(2)常規(guī)賦值太過麻煩, 而且破壞封裝.
這時候原型模式的優(yōu)勢便體現(xiàn)出來了。
3.Demo
首先創(chuàng)建一個Player類, 擁有2個屬性highestLevel和currentLevel, 同時提供2個public方法修改這2個屬性. 代碼如下:
@interface Player : NSObject <NSCopying>
/**
* update player's current level during game
*
* @param level
*/
- (void)updateCurrentLevel:(NSInteger)level;
/**
* update player's highest level during game
*
* @param level
*/
- (void)updateHighestLevel:(NSInteger)level;
@end
最為關(guān)鍵的是Player需要實(shí)現(xiàn)NSCopying協(xié)議:
#pragma mark - Override
- (instancetype)copyWithZone:(NSZone *)zone
{
Player *copyPlayer = [[[self class] allocWithZone:zone] init];
copyPlayer.highestLevel = self.highestLevel;
copyPlayer.currentLevel = self.currentLevel;
return copyPlayer;
}
這里大家看到NSZone類型, 這是個什么類型呢? 其實(shí)它是一個結(jié)構(gòu)體, 是為了防止內(nèi)存碎片化而引入的一個結(jié)構(gòu). NSZone會根據(jù)你想要開辟的內(nèi)存大小來分配內(nèi)存, 提高內(nèi)存管理. 然而官方的Programming with ARC Release Note也指出, 目前的runtime系統(tǒng)忽略了區(qū)域的概念,因?yàn)楸旧淼膬?nèi)存管理已經(jīng)非常有效率,使用Zone反而會降低內(nèi)存使用,訪問效率, 增加源代碼復(fù)雜度等.所以一般不使用NSZone, 而在這個例子中, 雖說使用了allocWithZone的方法, 但是我們進(jìn)去看源代碼則會發(fā)現(xiàn): Apple其實(shí)還是用一般的初始化方法代替了原來的Zone開辟:
#pragma mark - Override
- (instancetype)copyWithZone:(NSZone *)zone
+ (instancetype)allocWithZone:(struct _NSZone *)zone OBJC_SWIFT_UNAVAILABLE("use object
initializers instead");
原型設(shè)計(jì)模式基本就是這些, 當(dāng)然我們的Player類可以變成一個接口, 讓子類去實(shí)現(xiàn), 更好的體現(xiàn)面向接口編程.
結(jié)果:
2015-09-18 21:30:32.072 DP_Prototype[1173:280693] <Player: 0x14d513f60> 2015-09-18 21:30:32.073 DP_Prototype[1173:280693] <Player: 0x14d5337e0>
在其他文件調(diào)用copy方法, 即可看到系統(tǒng)為我們新開辟的一塊內(nèi)存, 引用計(jì)數(shù)為1.
4.Cocoa Touch框架中的對象復(fù)制
CocoaTouch框架為NSObject的派生類提供了實(shí)現(xiàn)深復(fù)制的協(xié)議。NSObject的子類需要實(shí)現(xiàn)NSCopying協(xié)議及其方法--(id)copyWithZone:(NSZone *)zone。NSObject有一個實(shí)例方法叫做(id)copy。默認(rèn)的copy方法調(diào)用[selfcopyWithZone:nil]。對于采納了NSCopying協(xié)議的子類,需要實(shí)現(xiàn)這個方法,否則將引發(fā)異常。IOS中,這個方法保持新的副本對象,然后將其返回。此方法的調(diào)用者需要負(fù)責(zé)釋放返回的對象。
深復(fù)制的技巧在于:保證確實(shí)復(fù)制了內(nèi)存中的資源,而不只是指指針。
- iOS App設(shè)計(jì)模式開發(fā)中對interpreter解釋器模式的運(yùn)用
- 詳解iOS App設(shè)計(jì)模式開發(fā)中對于享元模式的運(yùn)用
- iOS App設(shè)計(jì)模式開發(fā)中對建造者模式的運(yùn)用實(shí)例
- iOS App設(shè)計(jì)模式開發(fā)中對迭代器模式的使用示例
- iOS App的設(shè)計(jì)模式開發(fā)中對State狀態(tài)模式的運(yùn)用
- 解析iOS應(yīng)用開發(fā)中對設(shè)計(jì)模式中的抽象工廠模式的實(shí)現(xiàn)
- 詳解iOS應(yīng)用開發(fā)中使用設(shè)計(jì)模式中的抽象工廠模式
- 實(shí)例解析設(shè)計(jì)模式中的外觀模式在iOS App開發(fā)中的運(yùn)用
- 設(shè)計(jì)模式開發(fā)中的備忘錄模式在iOS應(yīng)用開發(fā)中的運(yùn)用實(shí)例
- 深入解析設(shè)計(jì)模式中的裝飾器模式在iOS應(yīng)用開發(fā)中的實(shí)現(xiàn)
相關(guān)文章
iOS 中Swift仿微信添加提示小紅點(diǎn)功能(無數(shù)字)
這篇文章主要介紹了iOS 中Swift仿微信添加提示小紅點(diǎn)功能(無數(shù)字),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-05-05iOS在頁面銷毀時如何優(yōu)雅的cancel網(wǎng)絡(luò)請求詳解
這篇文章主要給大家介紹了關(guān)于iOS在頁面銷毀時如何優(yōu)雅的cancel網(wǎng)絡(luò)請求的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05