今天寫程式時程式崩潰了,除錯了很久才找到了問題所在,一下是對這次問題的總結,希望對跟我這樣的新手有所幫助。如下:
在手動管理記憶體時應該注意,例項變數在定義為 retain 模式時,在呼叫初始化方法中不應該是自己手動賦值,而是呼叫setter方法。何為手動賦值?見下面:
在標頭檔案中宣告
@property (nonatomic, retain, getter = name) nsstring *_name;
這裡本意是想在 _name 每次賦值引用計數加1。而在 .m 檔案中如果初始化方法寫成:
- (id) initwithname:(nsstring*)name
的話,是
不對的。因為此時並沒有呼叫 setter 方法,而是手動的賦值了,所以引用計數值不會加1。如在其他地方寫如下語句:
//注:_per 為在某個類定義的例項變數
- (void) hello
當[str release] 執行後, _per.name 已經成為野指標。 即使執行 [str release]語句,當此函式一執行完,str也會被**, per 中的 _name 也還是會成為野指標。如果再次使用 per.name 可能導致程式崩潰或得不到想要的結果,原因是:如果在呼叫 per.name 之前沒有其他申請空間的操作,則可能會得到正確的結果,但是此時已經是不安全的資料了。如果在呼叫 per.name之前有其他申請空間的操作,那就會可能覆蓋了之前 str 所使用的位址的內容,此時如果申請空間的還是nsstring*型別,那之後使用 per.name 時就會得到錯誤的結果,而如果此時申請空間的是其他物件型別,那就會導致程式崩潰。
如:a. 在hello方法後面增加如下語句 或 在hello方法結束後緊接著執行的另乙個方法中的語句:
nsstring *newstr = [nsstring stringwithstring:@「nihao」]; //此時可能使用的就是剛才 str 的位址空間
nslog(@「%@「, _per.name); //輸出nihao
b. 在hello方法後面增加如下語句 或 在hello方法結束後緊接著執行的另乙個方法中的語句:
uilable *lable = [[uilable alloc] init]; //此時可能使用就是剛才 str 的位址空間
nslog(@「%@「, _per.name); //程式崩潰
所以,在初始化方法中應該寫成 self._name ,這樣才是呼叫setter方法。
以上是我今天遇到錯誤解決後的心得,有說錯的地方求批鬥指出!
OC 手動記憶體管理
一.為什麼要進行記憶體管理 建立乙個oc物件 定義乙個變數 呼叫乙個函式或者方法 二.oc中的記憶體管理是管理的記憶體中的哪一部分 我們知道 記憶體分為五大區域 棧區,堆區,資料去,bss段,區。而最後三者是在程式啟動時由作業系統進行控制的,所以不需要我們管理。棧區儲存的也都是已經初始化的基本資料型...
OC基礎 手動記憶體管理
建立物件 1.分配記憶體空間,儲存物件 2.初始化成員變數 3.反回物件的指標位址 1.物件在完成建立的同時,內部會自動建立乙個引用計數器,這個計數器,是系統用來判斷是否 物件的唯一依據,當我們的引用計數 retaincount 0 的時候,系統會毫不猶豫 當前物件 2.物件release reat...
OC語法 2 2 記憶體管理 手動記憶體管理2
五 copy語法 這篇建議學過foundation框架之後再學習 本小節知識點 基本用法 1 乙個物件可以使用 copy 或者mutablecopy 方法來建立物件的副本,當我們操作副本的時候不影響原物件 2 copy 需要先實現 nscopying 協議,建立的是不可變副本 如 nsstring,...