# 記憶體管理簡介
##1.記憶體管理的重要性
+建立乙個oc物件
+定義乙個變數
+呼叫乙個函式或者方法
##2.什麼是記憶體管理
-如何**那些不需要再使用的物件?
+那就得學會oc的記憶體管理
- 所謂記憶體管理, 就是對記憶體進行管理, 涉及的操作有:
+分配記憶體 : 比如建立乙個物件, 會增加記憶體占用
+清除記憶體 : 比如銷毀乙個物件, 能減小記憶體占用
- 記憶體管理的管理範圍
+任何繼承了nsobject的物件
+對其他非物件型別無效(int、char、float、double、struct、enum等 )
- 只有oc物件才需要進行記憶體管理的本質原因
+oc物件存放於堆裡面
+非oc物件一般放在棧裡面(棧記憶體會被系統自動**)
##3.堆和棧
- 棧(作業系統):由作業系統自動分配釋放,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧(先進後出);
- 堆(作業系統):一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os**,分配方式類似於鍊錶。
- 示例:
int main(int argc, const char * argv)
@autoreleasepool {
int a = 10; // 棧
int b = 20; // 棧
// p : 棧
// person物件(計數器==1) : 堆
person *p = [[person alloc] init];
// 經過上一行**後, 棧裡面的變數a\b\c都會被**
// 但是堆裡面的person物件還會留在記憶體中,因為它是計數器依然是1
return 0;
!([更多關於堆疊資訊](
# 野指標\空指標
##1.殭屍物件
- 已經被銷毀的物件(不能再使用的物件)
##2.野指標
- 指向殭屍物件(不可用記憶體)的指標
- 給野指標發訊息會報exc_bad_access錯誤
##3.空指標
- 沒有指向儲存空間的指標(裡面存的是nil, 也就是0)
- 給空指標發訊息是沒有任何反應的
- 為了避免野指標錯誤的常見辦法
+ 在物件被銷毀之後, 將指向物件的指標變為空指標
# 記憶體管理原則
##1.記憶體管理原則
- 蘋果官方規定的記憶體管理原則
+誰建立誰release :
* 如果你通過alloc、new或[mutable]copy來建立乙個物件,那麼你必須呼叫release或autorelease
+誰retain誰release:
* 只要你呼叫了retain,就必須呼叫一次release
- 總結一下就是
+有加就有減
+曾經讓物件的計數器+1,就必須在最後讓物件計數器-1
##2.多物件記憶體管理
- 單個物件的記憶體管理, 看起來非常簡單
- 如果對多個物件進行記憶體管理, 並且物件之間是有聯絡的, 那麼管理就會變得比較複雜
- 其實, 多個物件的管理思路 跟很多遊戲的房間管理差不多
+比如鬥地主 \ 勁舞團 \ qq音速
!(- 總的來說, 有這麼幾點管理規律
+只要還有人在用某個物件,那麼這個物件就不會被**
+只要你想用這個物件,就讓物件的計數器+1
+當你不再使用這個物件時,就讓物件的計數器-1
##3.set方法記憶體管理
- (1)retain需要使用的物件
- (2)release之前的物件
- (3)只有傳入的物件和之前的不同才需要release和retain
- (void)setroom:(room *)room
// 避免過度釋放
if (room != _room)
// 對當前正在使用的車(舊車)做一次release
[_room release];
// 對新車做一次retain操作
_room = [room retain];
##4.dealloc方法的記憶體管理
- (void)dealloc
// 當人不在了,代表不用房間了
// 對房間做一次release操作
[_roomrelease];
[super dealloc];
# @property練習
##1.@property練習
- 微博類(status)
+文字內容(text)
+配圖(picture)
+發表時間(createtime)
+作者(author)
+**的說說(repoststatus)
+**數(retweetcount)
+讚數(likecount)
- 作者類(author)
+暱稱(name)
+頭像(icon)
+生日(birthday)
+賬號(account)
- 賬號(account)
+賬號名稱(name)
+賬號密碼(pwd)
+賬號註冊時間(registertime)
模擬場景:
* 老王在2010-1-1 17:56:34註冊了乙個賬號
(名稱:[email protected],密碼:haomage)
* 老王的生日是1986-3-818:18:18
* 老王發布一條說說
* 文字內容 @「爆公尺花手機比逼格更有逼格」
* @「phone.png」
* 被**的說說: 沒有
* **數: 90
* 點讚數: 200
* 王大錘在2012-8-819:26:54註冊了乙個賬號
(名稱:[email protected], 密碼:654321)
* 王大錘的生日是1989-9-614:16:28
* 王大錘在2015-6-2120:47:09時,**了張三之前發布的說說,並且還附帶了一句話:@「真的很有逼格」
!(# @class
##1.@class基本概念
- 作用
+可以簡單地引用乙個類
- 簡單使用
+@class dog;
+僅僅是告訴編譯器:dog是乙個類;並不會包含dog這個類的所有內容
- 具體使用
+在.h檔案中使用@class引用乙個類
+在.m檔案中使用#import包含這個類的.h檔案
##2.@class其它應用場景
- 對於迴圈依賴關係來說,比方a類引用b類,同時b類也引用a類
- 這種巢狀包含的**編譯會報錯
#import "b.h"
@inte***ce a : nsobject
b*_b;
@end
#import 「a.h"
@inte***ce b : nsobject
a*_a;
@end
- 當使用@class在兩個類相互宣告,就不會出現編譯報錯
@class b;
@inte***ce a : nsobject
b*_b;
@end
@class a;
@inte***ce b : nsobject
a*_a;
@end
##3.@class和#import
- 作用上的區別
+#import會包含引用類的所有資訊(內容),包括引用類的變數和方法
+@class僅僅是告訴編譯器有這麼乙個類, 具體這個類裡有什麼資訊, 完全不知
- 效率上的區別
+如果有上百個頭檔案都#import了同乙個檔案,或者這些檔案依次被#import,那麼一旦最開始的標頭檔案稍有改動,後面引用到這個檔案的所有類都需要重新編譯一遍 , 編譯效率非常低
+相對來講,使用@class方式就不會出現這種問題了
# dealloc方法
##1.dealloc方法基本概念
- 當乙個物件的引用計數器值為0時,這個物件即將被銷毀,其占用的記憶體被系統**
- 物件即將被銷毀時系統會自動給物件傳送一條dealloc訊息
(因此, 從dealloc方法有沒有被呼叫,就可以判斷出物件是否被銷毀)
- dealloc方法的重寫
+一般會重寫dealloc方法,在這裡釋放相關資源,dealloc就是物件的遺言
+`一旦重寫了dealloc方法, 就必須呼叫[super dealloc],並且放在最後面呼叫
- 使用注意
+不能直接呼叫dealloc方法
+一旦物件被**了, 它占用的記憶體就不再可用,堅持使用會導致程式崩潰(野指標錯誤)
C C 語言之記憶體分配
一.理論 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,c語言中對應的主要函式有malloc 和free c 中是new和delete...
C語言之記憶體使用
問題 記憶體使用 有人寫了乙個將整數轉換為字串的函式 char itoa int n 如果我呼叫這個函式 char str5 itoa 5 str5會是什麼結果呢?答案分析 答案是不確定,可以確定的是肯定不是我們想要的 5 retbuf定義在函式體中,是乙個區域性變數,它的記憶體空間位於棧 stac...
深入C語言之記憶體問題
最近瘋狂學習c語言當中,看到有啟蒙文章,心中大喜,隨複製。記憶體,c語言中出現詭異bug的兩大 源泉 之一。即使是久經沙場的老手,也有時也難免落入陷阱。本文將涉足這個雷區,一 竟。本人菜鳥乙隻,屬於初探,不敢深挖。記憶體分為哪些段?一般來說,c語言中記憶體分為 棧 stack 堆 heap 全域性變...