OC語言之記憶體管理簡介

2021-07-10 02:16:23 字數 4357 閱讀 6016

# 記憶體管理簡介

##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 全域性變...