2016年11月20日星期日
深淺拷貝:
(可涉及的應用場景:值引用掉奄,對象引用)
淺:
- 只是針對指針的拷貝规个,拷貝后,兩個指針指向同一個內存空間姓建。
深:
- 不但對指針進行拷貝诞仓,而且對指針指向的內容進行拷貝,經過拷貝后的指針是指向兩個不同地址的指針速兔。
分類(category)和擴展(extension)
-
分類:使用分類可以在不進行子類化的情況下墅拭,為已經存在的類增加功能。分類中的方法會成為類的組成部分(在程序中)涣狗,并且會被其子類繼承帜矾。這意味著可以向這個類(或它的子類)發(fā)送消息,調用在分類中定義的方法屑柔。
分類通常用于:- 1.擴展其他人定義的類(即使你無法訪問他們的源代碼)屡萤;
- 2.替代子類;
- 3.將新類的實現代碼分發(fā)給多個源文件(通過多人分工掸宛,簡化大型類的開發(fā)工作)死陆。
-
類接口的聲明以關鍵字@interface開頭,后跟已經存在的類的名稱唧瘾、帶括號的分類名稱措译、以及它所接受的協(xié)議(如果有),以關鍵字@end結束饰序。方法的聲明應放在這些語句之間领虹。
- 分類的聲明語法
@interface 類的名稱(分類的名稱)
//方法的聲明
@end
- 例:
- 分類 Nuclear的接口代碼
#import "Atom.h"
@Interface Atom (Nuclear)
-(NSUInteger) atomicNumber;
@end
該分類聲明了一個名為atomicNumber的方法,這個方法會返回一個非負整形值求豫。
- ~
- 分類Nuclear的實現代碼
#import "Atom.h"
#import "Atom+Nuclear.h"
@implementation Atom (Nuclear)
-(NSUInteger) atomicNumber{
return self.protons;
}
這就實現了Nuclear分類塌衰,從而向Atom類及其子類添加了atomicNumber方法诉稍。
- 擴展:可以將擴展視為一種匿名(既未命名的)分類。在擴展中聲明的方法必須在相應類的主@implementation塊中實現(它們無法再分類中實現)最疆。
- 類擴展的語法
@interface 類的名稱 ()
{
//實例變量的聲明
}
//屬性的聲明
//方法的聲明
如上:擴展與分類的區(qū)別是它能夠聲明實例變量和屬性杯巨。編譯器會檢查在擴展中聲明的方法(和屬性)是否被實現。類擴展通常應存儲在類實現文件中(.m文件中)努酸,并用于組織和聲明在類中獨立使用的其他私有方法(例如服爷,不是公用api的一部分)。
堆和棧的概念區(qū)別:
- 堆
- 是大家共有的空間获诈,分全局堆和局部堆仍源。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間舔涎。堆在操作系統(tǒng)對進程初始化的時候分配笼踩,運行過程中也可以向系統(tǒng)要額外的堆,但是記得用完了要還給操作系統(tǒng)终抽,要不然就是內存泄漏戳表。堆里面一般放的是靜態(tài)數據,比如static的數據和字符串常量等昼伴,資源加載后一般也放在堆里面匾旭。一個進程的所有線程公用這些堆,所以對堆的操作要考慮同步和互斥的問題圃郊。程序里編譯后的數據段都是堆的一部分价涝。
- 棧
- 是一個線程獨有的,保存其運行狀態(tài)和局部自動變量的持舆。棧在線程開始的時候初始化色瘩,每個線程的棧相互獨立,因此逸寓,棧是 thread safe的居兆。每個c++對象的數據成員也存在在棧中,每個函數都有自己的棧竹伸,棧被用來在函數之間傳遞參數泥栖。操作系統(tǒng)在切換線程的時候會自動的切換棧,就是切換ss/esp寄存器勋篓。棸上恚控件不需要再高級語言里面顯示的分配和釋放禾酱。
堆和棧的理論知識:
-
1.申請方式
- stack:由系統(tǒng)自動分配呻袭,例如,聲明在函數中一個局部變量int b;系統(tǒng)自動在棧中為b開辟空間
- heap:需要程序員自己申請募谎,并指明大小拜银,在c中malloc函數
-
2.申請后系統(tǒng)的響應
- 棧:只要棧的聲譽空間大于所申請的空間殊鞭,系統(tǒng)將為程序提供內存遭垛,否則將報異常提示棧溢出。
- 堆:首先應該知道操作系統(tǒng)有一個記錄空閑內存地址的鏈表钱豁,當系統(tǒng)收到程序的申請的時耻卡,會遍歷該鏈表疯汁,尋找第一個空間大于所申請空間的堆結點牲尺,然后將該結點從空閑結點鏈表中刪除,并將該結點的空間分配給程序幌蚊,另外谤碳,對于大多數系統(tǒng),會在這塊內存空間中的首地址處記錄本次分配的大小溢豆,這樣蜒简,代碼中的delete語句才能正確的釋放本內存空間。另外漩仙,由于找到的堆結點的大小不一定正好等于申請的大小搓茬,系統(tǒng)會自動的將多余的那部分重新放入空閑鏈表中。
-
申請大小的限制
- 棧:在windows下队他,棧是向低地址擴展的數據結構卷仑,是一塊連續(xù)的內存區(qū)域。這句話的意思是棧頂的地址和棧的最大容量是系統(tǒng)預先規(guī)定好的麸折,在windows下锡凝,棧的大小是2m(也可能是1m,它是一個編譯時就確定的常數),如果申請的空間超過棧的剩余空間時垢啼,將提示overflow窜锯。因此,能從棧獲得的空間較小芭析。
- 堆:堆是向高地址擴展的數據結構锚扎,是不連續(xù)的內存區(qū)域。這是由于程序是用鏈表來存儲的空閑內存地址馁启,自然是不連續(xù)的驾孔,而鏈表的遍歷方向是由低向高。堆的大小受限于計算機系統(tǒng)中有效的虛擬內存进统。由此可見助币,堆獲得的空間比較靈活,也比較大螟碎。
-
申請效率的比較
- 棧:由系統(tǒng)自動分配眉菱,速度較塊。但程序員是無法控制的掉分。
- 堆:是由new分配的內存俭缓,一般速度比較慢克伊,而且容易產生內存碎片,不過用起來最方便华坦。
-
堆和棧的存儲內容:
- 棧:在函數調用時愿吹,第一個進程的是主函數中后的下一條指令(函數調用語句的下一條可執(zhí)行語句)的地址,然后是函數的各個參數惜姐,在大多數的C編譯器中犁跪,參數是由右往左入棧的,然后是函數中的局部變量歹袁。注意靜態(tài)變量是不入棧的坷衍。當本次函數調用結束后,局部變量最先出棧条舔,然后是參數枫耳,最后胡棧頂指針指向最開始存的地址,也就是主函數中的嚇一跳指令孟抗,程序由該點繼續(xù)運行迁杨。
- 堆:一般是在堆的頭部用一個字節(jié)存放堆的大小。堆中的具體內容有程序員安排凄硼。
<a >堆棧參考點</a>
總結:堆和棧的區(qū)別可以用如下的比喻來看:
使用棧就像我們去飯館里吃飯铅协,只管點菜(發(fā)出申請)、付錢帆喇、和吃(使用)警医,吃飽了就走,不必理會切菜坯钦、洗菜等準備工作和洗碗预皇、刷過等掃尾工作,他的好吃是快捷婉刀,但是自由度比較小吟温。
使用堆就像是自己動手做喜歡吃的菜肴,比較麻煩突颊,吃完之后還得清洗鲁豪、打掃等后續(xù)工作(不然用完了不清洗就不好再用),但是比較符合自己的口味律秃,而且自由度比較大爬橡。