iOS 局部變量和全局變量以及成員變量的區(qū)別

@interface Person : NSObject

{

? ? // 成員變量:

? ? // 寫在類聲明的大括號中的變量, 我們稱之為 成員變量(屬性, 實(shí)例變量)

? ? // 成員變量只能通過對象來訪問

? ? // 注意: 成員變量不能離開類, 離開類之后就不是成員變量 成員變量不能在定義的同時(shí)進(jìn)行初始化

? ? // 存儲: 堆(當(dāng)前對象對應(yīng)的堆的存儲空間中)

? ? // 存儲在堆中的數(shù)據(jù), 不會被自動釋放, 只能程序員手動釋放

? ? int age;

}

@end

————————————————

// 全局變量:

// 寫在函數(shù)和大括號外部的變量, 我們稱之為全局變量

// 作用域: 從定義的那一行開始, 一直到文件末尾

// 全局變量可以先定義在初始化, 也可以定義的同時(shí)初始化

// 存儲: 靜態(tài)區(qū)

// 程序一啟動就會分配存儲空間, 直到程序結(jié)束才會釋放

int a;

int b = 10;

int main(int argc, const char * argv[]) {

? ? // 局部變量:

? ? // 寫在函數(shù)或者代碼塊中的變量, 我們稱之為局部變量

? ? // 作用域: 從定義的那一行開始, 一直到遇到大括號或者return

? ? // 局部變量可以先定義再初始化, 也可以定義的同時(shí)初始化

? ? // 存儲 : 棧

? ? // 存儲在棧中的數(shù)據(jù)有一個(gè)特點(diǎn), 系統(tǒng)會自動給我們釋放

? ? int num = 10;

? ? {

? ? ? ? int value;

? ? }

? ? return 0;

}

————————

局部變量: 棧

全局/靜態(tài)變量: 靜態(tài)全局區(qū)

Objective-C 對象: 堆

對象和變量的區(qū)別

對象是一段存儲空間

變量由對象的聲明引入。變量的名稱表示對象。

NSObject*obj = [[NSObjectalloc] init];

這行代碼創(chuàng)建了一個(gè) NSObject 類型的指針 obj 和一個(gè) NSObject 類型的對象,obj 指針存儲在棧上,而其指向的對象則存儲在堆上(簡稱為堆對象)

2.retain

2.1 retain和屬性

我們可以通過屬性來保存對象,如果一個(gè)屬性為強(qiáng)引用,我們就可以通過屬性的實(shí)例變量和存取方法來對某個(gè)對象進(jìn)行操作,例如某個(gè)屬性的setter方法如下:

- (void)setPerson:(Person *)person {?

?[person retain];?

?[_person release];

_person = person;?

?}

我們通過retain新值,release舊值,再給實(shí)例變量更新值。需要注意的一點(diǎn)是:需要先retain新值,再release新值。因?yàn)槿绻屡f值是同一個(gè)對象的話,先release就有可能導(dǎo)致該對象被系統(tǒng)回收,再去retain就沒有任何意義了。

- (void)viewDidLoad {

[superviewDidLoad];

//實(shí)例變量持有Person類對象(P對象)。這樣賦值不會調(diào)用set方法

_person = [[Person alloc] init];

self.person = _person;//調(diào)用set方法

}

- (void)setPerson:(Person *)person {

//release釋放對P對象的引用,P對象引用計(jì)數(shù)值變?yōu)榱悖瑒tP對象被系統(tǒng)回收

[_person release];

//由于P對象已經(jīng)被回收,再去retain就容易出問題

[person retain];

_person = person;

}


我們都知道用@property 聲明的屬性 Xcode 會幫我們生成get set 方法,有時(shí)我們根據(jù)實(shí)際需要會重寫get 或者set 方法.都是可以的.但是我們get set 方法都重寫,就會報(bào)錯(cuò)?

-(void)setContact:(Contact?*)contact

{

//先判斷要傳值的對象里的值是否和要傳的值相同, 如果相同不需要開辟內(nèi)存空間, 也不需要做任何操作.?

//如果不相同. 將原有的內(nèi)存釋放, 再將屬性指向新的內(nèi)存.

? ??if?(_contact?!= contact) {

? ? ? ? //釋放

? ? ? ? [_contact?release];

? ? ? ? //contact引用計(jì)數(shù)加一

? ? ? ??_contact?= [contact?retain];

? ? }

1 屬性的setter方法和getter方法是不能同時(shí)進(jìn)行重寫的,這是因?yàn)?,一旦你同時(shí)重寫了這兩個(gè)方法,那么系統(tǒng)就不會幫你生成這個(gè)成員變量了,所以會報(bào)錯(cuò),如果真的就想非要重寫這個(gè)屬性的setter和getter方法的話,就要手動生成成員變量,然后就可以重寫了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容