iOS中的深只损、淺一姿、可變、不可變copy

這周由于公司招新人跃惫,面試官的一道關(guān)于copy和mutalbeCopy的問題引發(fā)了組員之間的激烈探討叮叹,這時有位號稱selfStrong的同學(xué)跑出了他的必殺技--葵花寶典,說關(guān)于深淺拷貝的問題爆存,看這張表就行了:



看到這張表蛉顽,臥槽,這不就是當(dāng)時教我們的口訣嗎:“copy-指針拷貝-淺拷貝先较,mutableCopy-內(nèi)容拷貝-深拷貝”携冤!,“只有不可變對象調(diào)用copy方法時是淺拷貝拇泣,其他情況都為深拷貝”噪叙。曾經(jīng)一段時間我確實也是靠是否mutable來區(qū)分深淺拷貝的,但經(jīng)過多次和毛毛可的探討和實際的測試霉翔,逐漸發(fā)現(xiàn)這種記憶方式的一些問題。

把拷貝方法稱為copy而非immutableCopy的原因在于苞笨,NSCopying不僅涉及給那些具有可變版本和不可變版本的類來使用债朵,而且還要供其他一些類使用,而那些類沒有“可變”與“不可變”之分瀑凝,所以說序芦,把拷貝方法叫做immutableCopy不合適。 ----Effective OC 2.0

深拷貝/淺拷貝本來就是是兩組不同的概念粤咪,可變/不可變只決定對象的可變性谚中,而拷貝這個概念本意就是產(chǎn)生一個對象的副本,至于是深拷貝還是淺拷貝,用毛毛可不知道從哪找的這句“deep copy copy everything”就能很好的判斷宪塔。因為OC中的copy(immutableCopy)磁奖、mutableCopy方法把可不可變和拷貝這兩種概念聯(lián)系在了一起,所以讓我們覺得是否可變和深淺拷貝兩者之間是一一對應(yīng)的關(guān)系的某筐,但其實想想swift或者別的語言我們肯定不會把var/let和copy/deepCopy聯(lián)系起來吧比搭。

所以單純的說copy就是指針拷貝/淺拷貝或者mutableCopy就是內(nèi)容拷貝/深拷貝只能說在某些情況下是有這種一一對應(yīng)的關(guān)系,但并不能作為一個放之四海而皆準(zhǔn)的判斷規(guī)則南誊,關(guān)于深淺拷貝的問題身诺,我們應(yīng)該按照不同的類型來區(qū)分。

容器類型

可以這樣總結(jié):

類型 操作 容器 內(nèi)容 操作返回容器的可變性 深淺拷貝
NS* copy 不可 /
NS* mutableCopy
NSMutable* copy 不可
NSMutable* mutableCopy
NS* initWithXX:copyItems: 不可
NSMutable* initWithXX:copyItems:

容器類默認的copy操作默認都是淺拷貝抄囚,默認都會生成一個新的容器(也就是開辟一塊新的內(nèi)存地址霉赡,至于NS類型返回就容器的問題下面會講到),要想實現(xiàn)容器類的深拷貝幔托,蘋果對于NS及其子類容器類型都提供了一個initWithXX:copyItems:的init方法同廉,給copyItems這個參數(shù)傳YES,該方法生成的新容器中的每個元素都相當(dāng)于對舊容器中相對應(yīng)的元素做了一次copy操作(前提是元素遵守了NSCopying協(xié)議)柑司,這樣新容器對象就是對舊容器對象的一份深拷貝迫肖。

或者利用歸檔和反歸檔技術(shù)來實現(xiàn)深拷貝:

//先將要拷貝的數(shù)組歸檔
NSMutableArray *dataArray = [NSMutableArray array];
NSdata *data = [NSKeyedArchiver archivedDataWithRootObject: dataArray];
//再將歸檔后的數(shù)據(jù)解檔賦值給新的數(shù)組
NSmutableArray *dataArray2 = [NSKeyedArchiver unarchiveOjjectWithData:data];

自定義對象類型:

1.首先遵守NSCopying\NSMutableCopying協(xié)議
2.重寫copyWithZone:/mutableCopyWithZone:方法并返回新對象

- (id)copyWithZone:(NSZone *)zone {
    ClassB *copyObject = [[[self class] allocWithZone:zone] init];
    copyObject.name = [self.name copy];
    return copyObject;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
    ClassB *mutableCopyObject = [[[self class] allocWithZone:zone] init];
    copyObject.name = [self.name mutableCopy];
    return mutableCopyObject
}

王老師提到的關(guān)于自定義對象的mutableCopy的使用場景的問題,我想了想攒驰,如果一個Person有一個NSArray類型的arr屬性蟆湖,他想產(chǎn)生一個能夠帶有mutableArr屬性的Person,那么就可以對這個Person對象進行mutableCopy操作玻粪,這樣copy出來的對象的屬性就都是mutable類型了隅津,比這樣相當(dāng)于對原來的對象進行一種“升級”,目前能想到的也只有這種場景了劲室。

NSString類型

和葵花寶典中的一致:

類型 操作 內(nèi)存 內(nèi)容 可變性 深淺拷貝
NSSting copy 不可 /
NSSting mutableCopy
NSMutableString copy 不可
NSMutableString mutableCopy

按理說copy這一操作都應(yīng)該開辟一塊新的內(nèi)存伦仍,至于為啥NSArray/NSString的copy返回的還是舊地址,我們推斷是蘋果做了優(yōu)化很洋,因為對NSArray/NSString這些不可變類型copy后生成的新內(nèi)容和原來是完全一樣的充蓝,如果還去開辟一片新的內(nèi)存地址就造成了浪費,所以對于NS*類型的copy操作喉磁,本質(zhì)上和=的作用一直谓苟,就是個單純的賦值操作,指向原來的對象协怒。

現(xiàn)階段對copy和mutableCopy的理解也就是這樣了涝焙,這樣分開理解感覺更容易理清楚copy/deepCopy和mutable/immutable之間的關(guān)系,有問題可以留言探討孕暇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仑撞,一起剝皮案震驚了整個濱河市赤兴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隧哮,老刑警劉巖桶良,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異近迁,居然都是意外死亡艺普,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門鉴竭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歧譬,“玉大人,你說我怎么就攤上這事搏存」宀剑” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵璧眠,是天一觀的道長缩焦。 經(jīng)常有香客問我,道長责静,這世上最難降的妖魔是什么袁滥? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮灾螃,結(jié)果婚禮上题翻,老公的妹妹穿的比我還像新娘。我一直安慰自己腰鬼,他們只是感情好嵌赠,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著熄赡,像睡著了一般姜挺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彼硫,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天炊豪,我揣著相機與錄音,去河邊找鬼乌助。 笑死溜在,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的他托。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼仆葡,長吁一口氣:“原來是場噩夢啊……” “哼赏参!你這毒婦竟也來了志笼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤把篓,失蹤者是張志新(化名)和其女友劉穎纫溃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體韧掩,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡紊浩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疗锐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坊谁。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖滑臊,靈堂內(nèi)的尸體忽然破棺而出口芍,到底是詐尸還是另有隱情,我是刑警寧澤雇卷,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布鬓椭,位于F島的核電站,受9級特大地震影響关划,放射性物質(zhì)發(fā)生泄漏小染。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一贮折、第九天 我趴在偏房一處隱蔽的房頂上張望裤翩。 院中可真熱鬧,春花似錦脱货、人聲如沸岛都。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臼疫。三九已至,卻和暖如春扣孟,著一層夾襖步出監(jiān)牢的瞬間烫堤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工凤价, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸽斟,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓利诺,卻偏偏與公主長得像富蓄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子慢逾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于OC中的copy、mutableCopy看過別人寫的很多文章口注,平時工作中也經(jīng)常用变擒,但并沒有驗證過,今天來...
    MinimalismC閱讀 2,365評論 0 2
  • 前言 不敢說覆蓋OC中所有copy的知識點寝志,但最起碼是目前最全的最新的一篇關(guān)于 copy的技術(shù)文檔了娇斑。后續(xù)發(fā)現(xiàn)有新...
    zyydeveloper閱讀 3,360評論 4 35
  • 本文為轉(zhuǎn)載: 作者:zyydeveloper 鏈接:http://www.reibang.com/p/5f776a...
    Buddha_like閱讀 877評論 0 2
  • 前言 過幾天準(zhǔn)備面試了,搜了搜晚上的面試題材部,好多好多毫缆。說實話我大部分都答不上來,也沒法全看败富,找了《招聘一個靠譜的i...
    叔叔不吃棒棒糖閱讀 274評論 0 2
  • 如果只能選一個兽叮,我最想學(xué)的技能是什么芬骄?這是一個值得深思的問題,目前就個人而言想做的事情太多鹦聪,舉例說來:想考英...
    刻盤閱讀 283評論 0 1