內存管理
什么是堆?什么是棧?
答:棧(操作系統):由操作系統自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧(先進后出);???????????????????????????????????????????????????????????????????????????????????? 堆(操作系統):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由系統回收,分配方式類似于鏈表。
什么是內存管理?
答:所謂內存管理, 就是對內存進行管理, 涉及的操作有:
分配內存 : 比如創建一個對象, 會增加內存占用
清除內存 : 比如銷毀一個對象, 能減小內存占用
內存管理的本質是什么?
答:OC對象存放于堆里面 ;非OC對象一般放在棧里面(棧內存會被系統自動回收)
MRC內存管理
什么是引用計數器?
答:每個OC對象都有自己的引用計數器,它是一個整數,表示有多少人正在用這個對象
引用計數器的作用?
答:(1)當使用alloc、new或者copy創建一個對象時,對象的引用計數器默認就是1;
(2)當對象的引用計數器為0時,對象占用的內存就會被系統回收;
如果對象的計數器不為0,那么在整個程序運行過程,它占用的內存就不可能被回收(除非整個程序已經退出 )
怎么操作引用計數器?
答:給對象發送一條retain消息,可以使引用計數器值+1(retain方法返回對象本身);
給對象發送一條release消息, 可以使引用計數器值-1;
給對象發送retainCount消息, 可以獲得當前的引用計數器值。
需要注意的是: release并不代表銷毀\回收對象, 僅僅是計數器-1。
dealloc 方法的作用?
答:對象即將被銷毀時系統會自動給對象發送一條dealloc消息 (因此, 從dealloc方法有沒有被調用,就可以判斷出對象是否被銷毀)
重寫dealloc方法有什么注意點?
答:重寫dealloc方法, [super dealloc]一定要寫到所有代碼的最后
內存管理的原則?
答:(1)誰創建誰release :如果你通過alloc、new、copy或mutableCopy來創建一個對象,那么你必須調用release或autorelease;(2)誰retain誰release:只要你調用了retain,就必須調用一次release;(3)循環引用,一邊用retain一邊用assign。
autorelease 自動釋放池
1.什么是自動釋放池?
答: autorelease是一種支持引用計數的內存管理方式,只要給對象發送一條autorelease消息,會將對象放到一個自動釋放池中,當自動釋放池被銷毀時,會對池子里面的所有對象做一次release操作
2.自動釋放池的優點是什么?
答: 不用再關心對象釋放的時間,不用再關心什么時候調用release
3.簡述自動釋放池的原理?
答: autorelease實際上只是把對release的調用延遲了,對于每一個autorelease,系統只是把該 Object放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有Object會被調用Release。
4.自動釋放池有哪些注意事項?
答: (1)在自動釋放池中創建了對象, 一定要調用autorelease,才會將對象放入自動釋放池中
(2)一個程序中可以創建N個自動釋放池, 并且自動釋放池還可以嵌套
(3)不要再自動釋放池中使用比較消耗內存的對象, 占用內存比較大的對象
(4)盡量不要再自動釋放池中使用循環, 特別是循環的次數非常多, 并且還非常占用內存
(5)千萬不要寫多次autorelease
(6)一個alloc/new對應一個autorelease或者release
5.自動釋放池是以什么形式存儲的?
答: 如果存在多個自動釋放池的時候, 自動釋放池是以 “棧” 的形式存儲在堆區
棧的特點: 先進后出
ARC內存管理
1:ARC的原理是什么?
答:當ARC開啟時,編譯器將自動在代碼合適的地方插入retain, release和autorelease,而作為程序猿,完全不需要擔心編譯器會做錯(除非開發者自己錯用ARC了)。
ARC有什么優點?
答: 1.完全消除了手動管理內存的煩瑣, 讓程序猿更加專注于app的業務
2.基本上能夠避免內存泄露
3.有時還能更加快速,因為編譯器還可以執行某些優化
ARC的原則是什么?什么是強指針?什么是弱指針?
答:只要還有一個強指針變量指向對象,對象就會保持在內存中
(1)強指針 :默認所有指針變量都是強指針 ,被__strong修飾的指針
(2)弱指針 :被__weak修飾的指針
ARC下@property修飾符有哪些?
答: strong : 用于OC對象, 相當于MRC中的retain
weak : 用于OC對象, 相當于MRC中的assign
assign : 用于基本數據類型, 跟MRC中的assign一樣
ARC中是怎么對對象進行內存管理的?
答: (1)ARC下單對象內存管理
(2)ARC下,所有的指針都是強指針
(3)ARC, A對象想擁有B對象, 那么就需要用一個強指針指向B對象
(4)A對象不用B對象了, 什么都不需要做, 編譯器會自動幫我們做
ARC怎么解決循環引用問題?
答: ARC和MRC一樣, 如果A擁有B, B也擁有A, 那么必須一方使用弱指針
也就是說 一端用strong ,一端用weak
類別 Category
1.類別的作用
答:有時我們需要在一個已經定義好的類中增加一些方法,而不想去重寫該類。可以使用類別對該類擴充新的方法。
注意:類別只能擴充方法,而不能擴充成員變量。
2.Category的作用?
答:(1)在不改變原來的類內容的基礎上,為類增加一些方法。
(2)一個龐大的類可以分模塊開發,由多個人來編寫,更有利于團隊合作
3.分類,原來類或者父類中的方法調用的順序?
答:先調用分類中的方法(最后參與編譯的分類優先),再調用原來類中的方法,最后掉用父類中的方法
匿名擴展Extension
1.什么是類擴展?
答:延展類別又稱為擴展(Extension),Extension是Category的一個特例
2.類擴展格式?
答:類擴展書寫格式
@interface 類名 ()
@end
3.類擴展的作用是什么?
答:寫在.m文件中,可以為某個類擴充一些私有的成員變量和方法
Block
什么是Block?
答:Block是iOS中一種比較特殊的數據類型,用來保存某一段代碼
Block的作用?
答:Block用來保存某一段代碼, 可以在恰當的時間再取出來調用
功能類似于函數和方法
Block的格式?
答:Block的格式:
返回值類型 (^block變量名)(形參列表) = ^(形參列表) {
};
Block對變量的用法
在block塊內部:1.局部變量相當于一個常量,其值不可更改;2.靜態局部變量的值可以修改:3.全局變量的值也可以更改。
如果在代碼塊內部需要對局部變量進行賦值操作,可以在局部變量定義時使用__block來修飾
__block int b1=1000;
void (^MYblock1)(void)=^{
b1++;
NSLog(@"b1=%d",b1);
int b2=11+b1;
NSLog(@"b2=%d",b2);
};
MYblock1();//1001,1012
b1++;
MYblock1();//1003 1014
協議
1.什么是協議?
答:其他語言有接口的概念,接口就是一堆方法的聲明沒有實現.
OC中沒有接口的概念,OC中的接口就是協議.
協議Protocol是由一系列的方法聲明組成的
2.書寫協議的格式?
答:格式:
@protocol 協議名稱
// 方法聲明列表
@end
3.一個類怎么遵循協議?
答:格式:
@interface 類名 : 父類 <協議名稱1, 協議名稱2,…>
@end
注意:
(1)一個類可以遵守1個或多個協議
(2)任何類只要遵守了Protocol,就相當于擁有了Protocol的所有方法聲明
4.協議和繼承有什么區別?
答:?(1)繼承之后默認就有實現, 而protocol只有聲明沒有實現
(2)相同類型的類可以使用繼承, 但是不同類型的類只能使用protocol
(3)protocol可以用于存儲方法的聲明, 可以將多個類中共同的方法抽取出來, 以后讓這些類遵守協議即可
5.什么是基協議?
答:基協議:是基協議,是最根本最基本的協議,其中聲明了很多最基本的方法。
注意:建議每個新的協議都要遵守NSObject協議
6.協議有哪些注意事項?
答:?(1)協議只能聲明方法, 不能聲明屬性
(2)父類遵守了某個協議, 那么子類也會自動遵守這個協議
(3)在OC中一個類可以遵守1個或多個協議
注意: OC中的類只能有一個父類, 也就是說OC只有單繼承
(4)OC中的協議又可以遵守其它協議, 只要一個協議遵守了其它協議, 那么這個協議中就會自動包含其它協議的聲明
7.協議中控制方法的能否實現的關鍵字是什么?各有什么作用?
(1)注意: 如果沒有使用任何關鍵字修飾協議中的方法, 那么該方法默認就是required的
(2)注意:@required和@optional僅僅使用程序員之間交流, 并不能嚴格的控制某一個遵守該協議的類必須要實現該方法, 因為即便不是實現也不會報錯, 只會報一個警告
(3)?@required ?:如果協議中的方法是@required的, 要求遵守協議的類實現@required所修飾的方法,如果沒有實現該方法, 那么會報一個警告
(4)?@optional ?:如果協議中的方法是@optional的, 遵守協議的類可選擇實現@optional所修飾的方法,如果沒有實現該方法, 那么不會報警告
代理
1.代理模式的應用場景?
答:(1)當A對象想監聽B對象的一些變化時, 可以使用代理設計模式
(2)當B對象發生一些事情, 想通知A對象的時候, 可以使用代理設計模式
(3)當對象A無法處理某些行為的時候,想讓對象B幫忙處理(讓對象B成為對象A的代理對象)
2.用什么類型來接收遵守協議的代理對象?
答:使用id類型接收代理對象
3.簡述一下協議的編寫規范?
答:(1)一般情況下, 當前協議屬于誰, 我們就將協議定義到誰的頭文件中
(2)協議的名稱一般以它屬于的那個類的類名開頭, 后面跟上protocol或者delegate
(3)協議中的方法名稱一般以協議的名稱protocol之前的作為開頭
(4)一般情況下協議中的方法會將觸發該協議的對象傳遞出去
4.一般情況下一個類中的代理屬于的名稱叫做 delegate
5.當某一個類要成為另外一個類的代理的時候,一般情況下在.h中用@protocol 協議名稱;告訴當前類 這是一個協議。在.m中用#import真正的導入一個協議的聲明
6.委托代理(degegate),目的是改變和傳遞控制鏈
Copy
1.使用copy功能的前提是什么?
答: 使用copy前提:需要遵守NSCopying協議,實現copyWithZone:方法
使用mutableCopy的前提:需要遵守NSMutableCopying協議,實現mutableCopyWithZone:方法
2.如何使用copy功能?
答:?一個對象可以調用copy或mutableCopy方法來創建一個副本對象
copy : 創建的是不可變副本(如NSString、NSArray、NSDictionary)
mutableCopy :創建的是可變副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
3.copy基本原則?
答:?修改源對象的屬性和行為,不會影響副本對象
修改副本對象的屬性和行為,不會影響源對象
4.為什么通過不可變對象調用了copy方法, 不會生成一個新的對象?
答:?因為原來的對象是不能修改的, 拷貝出來的對象也是不能修改的
既然兩個都不能修改, 所以永遠不能影響到另外一個對象, 那么已經符合需求
所以: OC為了對內存進行優化, 就不會生成一個新的對象
5.自定義類如何實現copy操作?
答:(1)以后想讓自定義的對象能夠被copy只需要遵守NSCopying協議
(2)實現協議中的- (id)copyWithZone:(NSZone *)zone
(3)在- (id)copyWithZone:(NSZone *)zone方法中創建一個副本對象, 然后將當前對象的值賦值給副本對象即可
copy內存管理
1.淺復制(淺拷貝,指針拷貝,shallow copy)
源對象和副本對象是同一個對象
源對象(副本對象)引用計數器+1,相當于做一次retain操作
本質是:沒有產生新的對象
2.深復制(深拷貝,內容拷貝,deep copy)
源對象和副本對象是不同的兩個對象
源對象引用計數器不變,副本對象計數器為1(因為是新產生的)
本質是:產生了新的對象
單例
1.什么是單例模式?
答:類的對象成為系統中唯一的實例,提供一個訪問點,供客戶類 共享資源
單例就是無論怎么創建都只能有一個實例對象
2.什么情況下使用單例?
答:(1)類只能有一個實例,而且必須從一個為人熟知的訪問點對其進行訪問,比如工廠方法。
(2)這個唯一的實例只能通過子類化進行擴展,而且擴展的對象不會破壞客戶端代碼。
3.創建單例對象的方法一般以什么開頭?
答:(1)一般情況下創建一個單利對象都有一個與之對應的類方法
(2)一般情況下用于創建單利對象的方法名稱都以share開頭, 或者以default開頭