一、NSObject和id
NSObject是所有類的基類,根據LSP NSObject指針就可以指向任意的OC對象
id:沒有類型的指針類型 返回值可id
- NSObject和id都是萬能指針,可以執行任意的OC對象
- 通過NSObject指針去調用對象的方法的時候,編譯器會做編譯檢查
- 通過id類型的指針去調用對象的方法的時候編譯器直接通過,無論你調用什麼方法
- id指針只能調用對象的方法,不能使用點語法,會直接編譯錯誤
//子類調用時返回得失新建的子類對象
+(id)person
{
return [self new];
}
二、instancetype
如果返回值類型中寫的是instancetype,那麼返回值類型就是該類本身。instancetype只能在返回值中使用
三、引用計數器
- 新創建1個對象,這個對象的引用計數器默認是1
- 當對象的引用計數器變爲0的時候,對象就會被系統立即回收,並自動調用dealloc方法
- 爲對象發送retain方法 對象的引用計數器就會加1
- 爲對象發送release消息 並不是回收對象,而是讓對象的引用計數器-1,當對象的引用計數器變爲0的時候,對象纔會被系統立即釋放
- 在系統回收對象的時候,會自動調用dealloc方法,重寫dealloc方法時,必須在最後一句代碼調用父類dealloc方法
四、內存管理
- 當多一個人使用對象的時候,應該先爲這個對象發送retain消息
- 當少一個人使用對象時,應該爲這個對象發送release消息
- 在ARC機制中,retain release dealloc 這些方法無法調用
- 有對象的創建,就要匹配一個release
- retain和release的次數要匹配
五、內存泄露
指一個對象沒有被及時回收,在該回收的時候沒有回收,一直駐留在內存當中直到程序結束纔回收
單個對象的內存泄漏情況
- 有對象的創建,而沒有對應的relase
- retain的次數和release的次數不匹配
- 在不適當的時候,爲指針賦值爲nil
Person *p1 = [Person new];
[p1 retain];
[p1 release];
[p1 release];
六、setter與內存
當屬性是1個OC對象時,將傳進來的對象賦值給當前對象的屬性,代表傳入的對象多了一個人引用,所以我們這裏應該先爲這個傳入的對象發送一條retain消息再賦值,如果_car原本指向一個對象則要先release,噹噹前對象銷燬的時候,代表屬性指向的對象少了一個人引用,就應該在dealloc中release
//標準的MRC內存管理代碼
-(void)setCar:(Car *)car
{
if(_car !=car){
[_car release];
_car = [car retain];
}
}
-(void)dealloc
{
[_car release];
[super dealloc];
}