知識(shí)點(diǎn)安插:如果訪問權(quán)限允許,objective-c 允許直接通過對(duì)象來訪問成員變量,
IOS 開發(fā)學(xué)習(xí)總結(jié) objectivec面向?qū)ο笾惡蛯?duì)象(下)
。語法格式:對(duì)象->成員變量名;
對(duì)象與指針
這里沿用上篇objective-c面向?qū)ο笾?mdash;—類和對(duì)象(上)的代碼。
在 FKPersonTest.m中,有這樣的代碼:
FKPerson* person = [[FKPerson alloc] init];
這行代碼產(chǎn)生了2個(gè)東西,一個(gè)是 person 變量,一個(gè)是 FKPerson 對(duì)象。這個(gè)FKPerson 對(duì)象被賦給person 變量。
從類的定義來看,FKPerson對(duì)象包含3個(gè)成員變量(2個(gè)暴露,1個(gè)隱藏),成員變量是需要內(nèi)存來存儲(chǔ)。因此,創(chuàng)建FKPerson對(duì)象時(shí),必須有對(duì)應(yīng)的內(nèi)存來存儲(chǔ)FKPerson對(duì)象的成員變量。FKPerson對(duì)象在內(nèi)存里的存儲(chǔ)示意圖:
有圖可以看出,FKPerson對(duì)象由多塊內(nèi)存組成,不同的內(nèi)存塊存儲(chǔ)了不同成員變量。當(dāng)把FKPerson對(duì)象賦值給FKPerson*
變量時(shí),其實(shí)是把FKPerson對(duì)象在內(nèi)存中的首地址賦給了FKPerson*
變量。FKPerson*類型的變量指向?qū)嶋H的對(duì)象。
本質(zhì)上說,類是一種指針類型的變量。因此,程序定義的FKPerson*類型只是存放一個(gè)地址值,它被保存在該 main()) 函數(shù)的動(dòng)態(tài)存儲(chǔ)區(qū),它指向?qū)嶋H的FKPerson對(duì)象,而真正的FKPerson對(duì)象存放在堆(heap) 內(nèi)存里。如下示意圖:
當(dāng)一個(gè)對(duì)象被成功創(chuàng)建后,這個(gè)對(duì)象將保存在堆內(nèi)存中,objective-c 不允許直接訪問堆內(nèi)存中的對(duì)象,只能通過該對(duì)象的指針變量來訪問對(duì)象。就是說,所有的對(duì)象都只能通過指針變量來訪問它們。堆內(nèi)存里的對(duì)象可以有多個(gè)指針,即多個(gè)指針變量可以指向同一個(gè)變量。
如果堆內(nèi)存里的對(duì)象沒有任何變量指向該對(duì)象,那么程序?qū)o法再訪問該對(duì)象,如果程序員不釋放該對(duì)象所占用的內(nèi)存,就會(huì)造成內(nèi)存泄露。
self 關(guān)鍵字
self 關(guān)鍵字總是指向調(diào)用該方法的對(duì)象。它的最大作用是:讓類中的一個(gè)方法訪問該類的另一個(gè)方法或成員變量。
self 總是代表當(dāng)前類的對(duì)象,當(dāng) self 出現(xiàn)在某個(gè)方法體中時(shí),它所代表的對(duì)象是不確定的。但它的類型是確定的:它代表的對(duì)象只能是當(dāng)前類的示例。當(dāng)這個(gè)方法被調(diào)用時(shí),它代表的對(duì)象才能確定下來:誰調(diào)用該方法,self 就代表誰。
示例代碼:
頭文件:FKDog.h
<code class="hljs" bjectivec="">#import<foundation foundation.h="">@interface FKDog : NSObject// 定義一個(gè)jump方法- (void) jump;// 定義一個(gè)run方法,run方法需要借助jump方法- (void) run;@end</foundation></code>
實(shí)現(xiàn)文件:FKDog.m
<code class="hljs" bjectivec="">#import FKDog.h@implementation FKDog// 實(shí)現(xiàn)一個(gè)jump方法- (void) jump{ NSLog(@正在執(zhí)行jump方法);}// 實(shí)現(xiàn)一個(gè)run方法,run方法需要借助jump方法- (void) run{// FKDog* d = [[FKDog alloc] init];// [d jump]; [self jump]; NSLog(@正在執(zhí)行run方法);}@end</code>
FKDogTest.m文件:
<code class="hljs" java="">#import<foundation foundation.h="">#import FKDog.hint main(int argc , char * argv[]) { @autoreleasepool{ // 創(chuàng)建Dog對(duì)象 FKDog* dog = [[FKDog alloc] init]; // 調(diào)用Dog對(duì)象的run方法 [dog run]; }}</foundation></code>
用self區(qū)分重名的局部變量和成員變量
局部變量和成員變量重名的情況下,局部變量會(huì)隱藏成員變量,
電腦資料
《IOS 開發(fā)學(xué)習(xí)總結(jié) objectivec面向?qū)ο笾惡蛯?duì)象(下)》(http://www.oriental01.com)。為了在方法中強(qiáng)行引用成員變量,可以使用 self 關(guān)鍵字進(jìn)行區(qū)分。示例代碼:
FKWolf.h文件
<code class="hljs" bjectivec="">#import<foundation foundation.h="">@interface FKWolf : NSObject{ NSString* _name; int _age;}// 定義一個(gè)setName:ageAge方法- (void) setName: (NSString*) _name andAge: (int) _age;// 定義一個(gè)info方法- (void) info;@end</foundation></code>
FKWolf.m 文件
<code class="hljs" bjectivec="">#import FKWolf.h@implementation FKWolf// 定義一個(gè)setName:ageAge方法- (void) setName: (NSString*) _name andAge: (int) _age{ // 當(dāng)局部變量隱藏成員變量時(shí), // 可用self代表調(diào)用該方法的對(duì)象,這樣即可為調(diào)用該方法的成員變量賦值了。 self->_name = _name; self->_age = _age;}// 定義一個(gè)info方法- (void) info{ NSLog(@我的名字是%@, 年齡是%d歲 , _name , _age);}@endint main(int argc , char * argv[]) { @autoreleasepool{ FKWolf* w = [[FKWolf alloc] init]; [w setName: @灰太狼 andAge:8]; [w info]; }}</code>
把 self 當(dāng)成普通方法的返回值
當(dāng) self 作為對(duì)象的默認(rèn)引用使用時(shí),程序可以像訪問普通指針變量一樣訪問這個(gè) self引用,甚至可以把 self 當(dāng)成普通方法的返回值。
示例程序:
ReturnSel.m文件
<code class="hljs" bjectivec="">#import<foundation foundation.h="">@interface ReturnSelf : NSObject{ @public int _age;}- (ReturnSelf*) grow;@end@implementation ReturnSelf- (ReturnSelf*) grow{ _age++; // return self,返回調(diào)用該方法的對(duì)象 return self;}@endint main(int argc , char * argv[]){ @autoreleasepool{ ReturnSelf* rt = [[ReturnSelf alloc] init]; //可以連續(xù)調(diào)用同一個(gè)方法 [[[rt grow] grow] grow]; NSLog(@rt的_age成員變量的值是:%d , rt->_age); }}</foundation></code>
說明:使用 self 作為方法的返回值可以使代碼更加簡(jiǎn)潔,但可能造成實(shí)際意義的模糊。
id 類型
id 類型可以代表所有對(duì)象的類型。任意類的對(duì)象都可賦值給 id 類型的變量。
通過 id 類型的變量來調(diào)用方法時(shí),objective-c 將會(huì)執(zhí)行動(dòng)態(tài)綁定。動(dòng)態(tài)綁定:objective-c 將會(huì)跟蹤對(duì)象所屬的類,會(huì)在運(yùn)行時(shí)判斷該對(duì)象所屬的類,并在運(yùn)行時(shí)確定需要?jiǎng)討B(tài)調(diào)用的方法,而不是在編譯時(shí)確定要調(diào)用的方法。
示例程序:
<code class="hljs" bjectivec="">#import<foundation foundation.h="">#import FKPerson.hint main(int argc , char * argv[]) { @autoreleasepool{ // 定義id類型的變量,并將FKPerson對(duì)象賦給該變量 id p = [[FKPerson alloc] init]; // 使用p變量來調(diào)用say:方法。 // 程序?qū)⒃谶\(yùn)行時(shí)執(zhí)行動(dòng)態(tài)綁定,因此實(shí)際執(zhí)行FKPerson對(duì)象的say:方法 [p say: @你好,瘋狂iOS講義]; }}</foundation></code>