1. 堆和棧
1.1為什么有堆和棧缸沃? :
移動(dòng)設(shè)備的內(nèi)存是有限的,每個(gè)App所占的內(nèi)存都有一定限制修械,所以需要堆和棧來管理內(nèi)存趾牧。
1.2 App占用手機(jī)內(nèi)存的行為有:
- 創(chuàng)建一個(gè)OC對(duì)象
- 定義一個(gè)變量
- 調(diào)用一個(gè)函數(shù)或者方法
1.3 內(nèi)存管理的范圍和原因:
- 只有OC對(duì)象需要內(nèi)存管理,基本數(shù)據(jù)類型不需要進(jìn)行數(shù)據(jù)管理
- OC對(duì)象一般存儲(chǔ)在堆里肯污,由于堆內(nèi)存是動(dòng)態(tài)分配的翘单,所以堆內(nèi)存需要程序員手動(dòng)回收吨枉;非OC對(duì)象存儲(chǔ)在棧中,棧內(nèi)存會(huì)被系統(tǒng)自動(dòng)回收哄芜。
- 對(duì)于對(duì)象而言貌亭,棧內(nèi)存用于存放對(duì)象的指針,堆內(nèi)存用于存放對(duì)象
內(nèi)存中的五大區(qū)域
- 棧區(qū)
- 堆區(qū)
- BSS段
- 數(shù)據(jù)段
- 代碼段
- 棧:存儲(chǔ)局部變量认臊,當(dāng)其作用域執(zhí)行完畢之后圃庭,就會(huì)被系統(tǒng)立即收回
- 堆:存儲(chǔ)OC對(duì)象,手動(dòng)申請(qǐng)的字節(jié)空間失晴,需要調(diào)用free來釋放
- BSS段:未初始化的全局變量和靜態(tài)變量剧腻,一旦初始化就會(huì)從BSS段中回收掉,轉(zhuǎn)存到數(shù)據(jù)段中
- 數(shù)據(jù)段(常量區(qū)):存儲(chǔ)已經(jīng)初始化的全局變量和靜態(tài)變量涂屁,以及常量數(shù)據(jù)书在,直到結(jié)束程序時(shí)才會(huì)被立即收回
- 代碼段:代碼,直到結(jié)束程序時(shí)才會(huì)被立即收回
2. 進(jìn)程和線程
- 線程和進(jìn)程的區(qū)別主要在于它們是不同的操作系統(tǒng)資源管理方式拆又。進(jìn)程有獨(dú)立的地址空間蕊温,一個(gè)進(jìn)程崩潰后,在保護(hù)模式的影響下不會(huì)對(duì)其他進(jìn)程產(chǎn)生影響遏乔,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。
- 線程有自己的堆棧和局部變量发笔,但線程之間沒有單獨(dú)的地址空間盟萨,一個(gè)線程死掉就等同于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯了讨,但在進(jìn)程切換時(shí)捻激,耗費(fèi)資源較大,效率要差一些前计。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作胞谭,只能用線程,不能用進(jìn)程男杈。
- 進(jìn)程屬于資源分配和調(diào)度的單位丈屹,而線程是處理機(jī)調(diào)度和分配的單位
- 系統(tǒng)切換線程的代價(jià)比切換進(jìn)程要低;
3. 引用和指針
- 引用可以表示指針
- 引用和指針都是實(shí)現(xiàn)多態(tài)效果的手段
- 引用本身是目標(biāo)變量的別名伶棒,對(duì)引用的操作就是對(duì)目標(biāo)變量的操作
- 指針只是一個(gè)地址旺垒,是指向某個(gè)對(duì)象的一串內(nèi)存地址。一個(gè)引用對(duì)象肤无,其實(shí)就是被引用的對(duì)象它本身先蒋。指針的指向是可以改變的,而引用是不能改變的宛渐。
4. 局部變量和全局變量
- 局部變量的生命周期只在代碼塊內(nèi)
- 全局變量貫穿整個(gè)程序的生命周期
5. @property竞漾、@synthesize眯搭、@dynamic
- @property的本質(zhì):
@property = ivar + getter + setter
- ivar是成員變量,以下劃線開頭业岁,property是屬性鳞仙。
- 使用@synthesize 只有一個(gè)目的——給實(shí)例變量起個(gè)別名,或者說為同一個(gè)變量添加兩個(gè)名字叨襟。
- 如果要阻止自動(dòng)合成繁扎,記得使用@dynamic。經(jīng)典的使用場(chǎng)景是你知道已經(jīng)在某處實(shí)現(xiàn)了getter/setter 方法糊闽,而編譯器不知道的情況梳玫。
- @synthesize 的作用:是為屬性添加一個(gè)實(shí)例變量名,或者說別名右犹。同時(shí)會(huì)為該屬性生成 setter/getter 方法提澎。
- @synthesize:如果某屬性已經(jīng)在某處實(shí)現(xiàn)了自己的 setter/getter ,可以使用 @dynamic 來阻止 @synthesize 自動(dòng)生成新的 setter/getter 覆蓋。
- 內(nèi)存管理:@synthesize 和 ARC 無關(guān)念链。
- 使用:一般情況下無需對(duì)屬性添加 @synthesize 盼忌,但一些特殊情形仍然需要,例如protocol中聲明的屬性掂墓。
6. +load()和 +initialize()
- load和initialize方法都會(huì)在實(shí)例化對(duì)象之前調(diào)用谦纱,以main函數(shù)為分水嶺,前者在main函數(shù)之前調(diào)用君编,后者在之后調(diào)用跨嘉。
- +initialize 方法會(huì)在類收到第一個(gè)消息時(shí)調(diào)用,是一個(gè)懶加載的方式吃嘿,如果一直沒收到消息祠乃,則永不調(diào)用。這種設(shè)計(jì)節(jié)省了資源
- +load方法是系統(tǒng)根據(jù)方法地址直接調(diào)用兑燥,并不是objc_msgSend函數(shù)調(diào)用(isa亮瓷,superClass);這就決定了如果子類沒有實(shí)現(xiàn)+load方法降瞳,那么當(dāng)它被加載時(shí)runtime是不會(huì)調(diào)用父類的+load方法的嘱支,除非父類也實(shí)現(xiàn)了+load方法;
7. OC程序的編譯挣饥、鏈接斗塘、執(zhí)行
- 在.m文件中寫上符合OC語法規(guī)范的源代碼
生成main.m
- 使用編譯器將源代碼編譯成目標(biāo)文件
命令行 : cc -c mian.m
- 預(yù)處理
- 檢察語法
- 編譯
將 main.m -> main.o
- 鏈接
命令行 :cc mian.o - framework Foundation
告訴編譯器用到了哪些框架,去哪兒找這些框架
生成可執(zhí)行文件 main.o -> a.out
9. @try亮靴、@catch馍盟、@finally有什么用?
- try可以讓程序拋出異常后不立即崩潰茧吊,在處理完異常后可以繼續(xù)執(zhí)行后面的代碼
@try
{
//把可能拋出異常的代碼放在這里
}
@catch(NSException *ex){
//如果拋出異常贞岭,則在這里處理
}
@finally
{
//無論是否發(fā)生異常八毯,都會(huì)執(zhí)行這段代碼
}
- 當(dāng)@try中的代碼發(fā)生了異常,發(fā)生異常后面的代碼不會(huì)執(zhí)行瞄桨,會(huì)立即轉(zhuǎn)到@catch中话速,如果沒發(fā)生異常,會(huì)執(zhí)行完@try后跳過@catch芯侥。@catch只會(huì)在@try發(fā)生異常時(shí)執(zhí)行
- @finally無論在是否發(fā)生異常泊交,都會(huì)執(zhí)行@finally里面的代碼
10. 類方法和對(duì)象方法
- 類方法中不能訪問屬性,不能調(diào)用對(duì)象方法柱查;對(duì)象方法中可以直接調(diào)用類方法廓俭。
- 類的屬性是存在對(duì)象中的,一個(gè)類被加載時(shí)唉工,并不會(huì)創(chuàng)建對(duì)象研乒,所以調(diào)用類方法時(shí),是直接訪問內(nèi)存中的代碼段淋硝,并沒有屬性可以訪問雹熬。
- 類方法需要通過類名調(diào)用,不能用self調(diào)用谣膳,self代表類對(duì)象竿报。
- 類方法比對(duì)象方法更節(jié)約空間,效率更高继谚。
- 當(dāng)方法不需要訪問屬性仰楚,也不用調(diào)用其他對(duì)象方法,就可以用類方法犬庇。
11. instancetype的含義
- instancetype作為返回值時(shí),代表了當(dāng)前這個(gè)類的對(duì)象
12. static的含義
- static 不能修飾屬性和方法
- static可以修飾方法中的局部變量侨嘀,如果方法中的局部變量被static修飾臭挽,就會(huì)變成靜態(tài)變量,會(huì)儲(chǔ)存在常量區(qū)咬腕,當(dāng)方法結(jié)束欢峰,不會(huì)被回收。
12. self關(guān)鍵字
- self是一個(gè)指針涨共,在對(duì)象方法中纽帖,self指向當(dāng)前對(duì)象;在類方法中举反,self指向當(dāng)前類
- 當(dāng)方法中有和屬性同名的變量懊直,默認(rèn)先使用變量而不是屬性,要想使用屬性火鼻,必須調(diào)用self
- 在方法中想調(diào)用當(dāng)前對(duì)象的的另一個(gè)方法室囊,也需要用到self
- 在類方法中使用self雕崩,self代表了當(dāng)前類在代碼段中的地址,可以用在類方法中調(diào)用其他類方法融撞。
13. super的含義
- 在對(duì)象方法調(diào)用super盼铁,super代表調(diào)用從父類繼承過來的對(duì)象方法
- 在類方法調(diào)用super,super代表調(diào)用從父類繼承過來的類方法
14. @private尝偎、@protected饶火、@public
- @private修飾的屬性,只能在本類內(nèi)部訪問
- @protected修飾的屬性致扯,只能在本類和子類中訪問(不寫默認(rèn)是@protected)
- @public修飾的屬性肤寝,可以在任意地方訪問
- 子類任然可以繼承父類的私有屬性,只不過不能直接訪問父類的私有屬性
- 將屬性定義在@implementation中急前,外界訪問不到醒陆,任何修飾符都無效
15.description
- NSObject中description方法用來打印對(duì)象的信息<類名:對(duì)象地址>
- 重寫description可以自定義打印信息
16.什么是SEL?
- SEL叫做selector方法選擇器裆针,是一個(gè)類
- SEL對(duì)象用來存儲(chǔ)一個(gè)方法
- 類對(duì)象存儲(chǔ)方法的過程:
- 創(chuàng)建一個(gè)SEL對(duì)象
- 將方法的信息(方法類型刨摩,返回值,方法名世吨,方法參數(shù)澡刹,方法體)存儲(chǔ)在SEL對(duì)象中
- 再將SEL對(duì)象作為類對(duì)象的屬性存儲(chǔ)
SEL s1 = @selector(methodName)
17. 點(diǎn)語法的本質(zhì)
- 當(dāng)點(diǎn)語法在等號(hào)的左邊(self.age = xx),會(huì)調(diào)用屬性的setter方法
- 當(dāng)點(diǎn)語法在等號(hào)的左邊(int a = self.age)耘婚,會(huì)調(diào)用屬性的getter方法