@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方法的話,就要手動生成成員變量,然后就可以重寫了。