2.1 內(nèi)存消耗
- 2.1.1 棧大小
1.每個線程都有專用的椬钪眩空間
2.每個方法都有自己的棧幀抓艳,并消耗整體的棾鄞空間,棧幀會消耗一定字節(jié)的內(nèi)存
3.復雜頁面會遞歸調(diào)用layoutSubViews和drawRect方法娜饵,如果層級過深,可能會導致棧溢出
- 2.1.2 堆大小
1.每個進程的所有線程共享一個堆
2.一個應用可以使用的堆大小遠遠小于設(shè)備的RAM值
2.2 內(nèi)存管理模型
- 當一個對象創(chuàng)建于某個方法的內(nèi)部時官辈,那該方法就持有了這個對象
- 如果這個對象從方法返回箱舞,則調(diào)用者持有該對象
2.3 自動釋放對象
- 自動釋放對象讓你能放棄對一個對象的持有關(guān)系,但延后對它的銷毀
- 使用autorelease的引用計數(shù)有如下規(guī)則:
1.持有的對象是alloc方法返回的
2.不需要再使用release
3.使用autorelease表明你想要放棄持有關(guān)系拳亿,同時允許方法的調(diào)用者在對象唄釋放之前使用對象
2.4 autoreleasepool
- autoreleasepool是允許你放棄對一個對象的持有關(guān)系晴股,但可避免它立即被回收的一個工具
- 塊中收到過aurolease消息的所有對象都會在autoreleasepool塊結(jié)束時收到release消息。
2.5 自動引用計數(shù)
- ARC規(guī)則如下:
1.不能用retain风瘦,release队魏,autorelease,retainCount方法
2.可以實現(xiàn)dealloc万搔,但是不能調(diào)用
3.不能在C語言的結(jié)構(gòu)體內(nèi)使用對象指針
4.id和void *不能自動轉(zhuǎn)換胡桨,需要顯示轉(zhuǎn)換
5.屬性不能以new開頭
2.6 引用類型
- 默認的引用類型是強引用
- 被強引用指向的內(nèi)存不會被釋放
- 強引用會對引用計數(shù)加1,從而拓展對象的生命周期
- 弱引用是一種特殊的引用類型瞬雹。它不會增加引用計數(shù)昧谊,因而不會拓展對象的生命周期
- __weak具有安全性,對象被回收時酗捌,指針將自動被設(shè)置為nil
- __unsafe_unretained和__weak相似呢诬,但不能在對象被回收時涌哲,自動設(shè)置為nil
- assign,unsafe_unretained只應該用于值類型
2.8 僵尸對象
- 僵尸對象用于捕捉內(nèi)存錯誤的調(diào)試功能
- 通常情況下尚镰,當引用計數(shù)降為0時阀圾,對象會被立即被釋放,使得調(diào)試困難狗唉。如果開啟了僵尸對象初烘,那么對象不會被立即釋放,而是標記為僵尸分俯。
- 任何訪問僵尸對象的行為都會被記錄肾筐,因此可以排查問題
- NSZombieEnabled是一個環(huán)境變量,可以控制Core Foundation的運行時是否將使用僵尸對象
- 不應該長期保留NSZombieEnabled,因為牧人情況下不會有對象唄真正析構(gòu)缸剪,這會導致應用使用大量內(nèi)存吗铐。
- 發(fā)布前要禁用NSZombieEnabled
2.10 循環(huán)引用
- 引用計數(shù)的最大陷阱在于不能處理環(huán)狀的引用關(guān)系
2.11 弱類型:id
- 由于可以把任何消息都發(fā)送給id類型的對象,會出現(xiàn)編譯器不報錯的問題杏节,代碼如下:
@interface Test:NSObject
- (void)test1;
@end
@implementation Test
- (void)test1 {
NSLog(@"xxxx");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *ary = @[@"a",@"a",@"a"];
[ary[1] test1];
}
return 0;
}
- 上述ary[1]得到的為id類型的實例唬渗,且沒有提示沒定義test1函數(shù)等錯誤信息,是因為編譯器會根據(jù)所調(diào)用的方法名稱遍歷查找導入的頭文件以匹配的方法名奋渔,然后通過找到第一個匹配的方法獲取參數(shù)長度
- 解決方案:
1.[(NSString*)ary[1] test1]; 顯示調(diào)用谣妻,編譯器會直接在對應類型中查找
2.開啟編譯器警告"Strict Selector Matching",開啟后在你id類型實例發(fā)送方法時卒稳,若多個類有完全相同的方法簽名(名稱和參數(shù))時會有警告,但開啟后會導致內(nèi)置的框架產(chǎn)生許多警告蹋半,出現(xiàn)一堆不必要警告
- 在常規(guī)命名中盡量避免使用id類型
2.13 單例
- 依賴注入:需要時傳遞依賴,將依賴以外界傳入充坑,而不是說在本類進行實例化减江,將實例化的過程外放
2.15 最佳實踐
- 常用最佳實踐:
1.避免大量使用單例
2.不要設(shè)計出萬能類,(盡量職責單一)
3.對數(shù)值屬性(SEL,CGFloat等)用assign
4.對block屬性捻爷,使用copy
5.避免在block中直接使用外部的變量辈灼,@weakify,@strongify
6.注意銷毀定時器也榄、移除通知巡莹、解除回調(diào)
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者