IOS 開發學習總結 objective-c物件導向之——類和對象(下)

來源:互聯網
上載者:User

IOS 開發學習總結 objective-c物件導向之——類和對象(下)

知識點安插:如果存取權限允許,objective-c 允許直接通過對象來訪問成員變數。文法格式:對象->成員變數名;

對象與指標

這裡沿用上篇objective-c物件導向之——類和對象(上)的代碼。
在 FKPersonTest.m中,有這樣的代碼:
FKPerson* person = [[FKPerson alloc] init];
這行代碼產生了2個東西,一個是 person 變數,一個是 FKPerson 對象。這個FKPerson 對象被賦給person 變數。
從類的定義來看,FKPerson對象包含3個成員變數(2個暴露,1個隱藏),成員變數是需要記憶體來儲存。因此,建立FKPerson對象時,必須有對應的記憶體來儲存FKPerson對象的成員變數。FKPerson對象在記憶體裡的儲存:

有圖可以看出,FKPerson對象由多塊記憶體組成,不同的記憶體Block Storage了不同成員變數。當把FKPerson對象賦值給FKPerson*變數時,其實是把FKPerson對象在記憶體中的首地址賦給了FKPerson*變數。FKPerson*類型的變數指向實際的對象。
本質上說,類是一種指標類型的變數。因此,程式定義的FKPerson*類型只是存放一個地址值,它被儲存在該 main()) 函數的動態儲存裝置區,它指向實際的FKPerson對象,而真正的FKPerson對象存放在堆(heap) 記憶體裡。如下:

當一個對象被成功建立後,這個對象將儲存在堆記憶體中,objective-c 不允許直接存取堆記憶體中的對象,只能通過該對象的指標變數來訪問對象。就是說,所有的對象都只能通過指標變數來訪問它們。堆記憶體裡的對象可以有多個指標,即多個指標變數可以指向同一個變數。
如果堆記憶體裡的對象沒有任何變數指向該對象,那麼程式將無法再訪問該對象,如果程式員不釋放該對象所佔用的記憶體,就會造成記憶體泄露。

self 關鍵字

self 關鍵字總是指向調用該方法的對象。 它的最大作用是:讓類中的一個方法訪問該類的另一個方法或成員變數。

self 總是代表當前類的對象,當 self 出現在某個方法體中時,它所代表的對象是不確定的。但它的類型是確定的:它代表的對象只能是當前類的樣本。當這個方法被調用時,它代表的對象才能確定下來:誰調用該方法,self 就代表誰。
範例程式碼:
標頭檔:FKDog.h

#import @interface FKDog : NSObject// 定義一個jump方法- (void) jump;// 定義一個run方法,run方法需要藉助jump方法- (void) run;@end

實現檔案:FKDog.m

#import FKDog.h@implementation FKDog// 實現一個jump方法- (void) jump{    NSLog(@正在執行jump方法);}// 實現一個run方法,run方法需要藉助jump方法- (void) run{//  FKDog* d = [[FKDog alloc] init];//  [d jump];    [self jump];    NSLog(@正在執行run方法);}@end

FKDogTest.m檔案:

#import #import FKDog.hint main(int argc , char * argv[]) {    @autoreleasepool{        // 建立Dog對象        FKDog* dog = [[FKDog alloc] init];        // 調用Dog對象的run方法        [dog run];    }}
用self區分重名的局部變數和成員變數

局部變數和成員變數重名的情況下,局部變數會隱藏成員變數。為了在方法中強行引用成員變數,可以使用 self 關鍵字進行區分。
範例程式碼:
FKWolf.h檔案

#import @interface FKWolf : NSObject{    NSString* _name;    int _age;}// 定義一個setName:ageAge方法- (void) setName: (NSString*) _name andAge: (int) _age;// 定義一個info方法- (void) info;@end

FKWolf.m 檔案

#import FKWolf.h@implementation FKWolf// 定義一個setName:ageAge方法- (void) setName: (NSString*) _name andAge: (int) _age{    // 當局部變數隱藏成員變數時,    // 可用self代表調用該方法的對象,這樣即可為調用該方法的成員變數賦值了。    self->_name = _name;    self->_age = _age;}// 定義一個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];    }}
把 self 當成普通方法的傳回值

當 self 作為對象的預設引用使用時,程式可以像訪問普通指標變數一樣訪問這個 self引用,甚至可以把 self 當成普通方法的傳回值。
樣本程式:
ReturnSel.m檔案

#import @interface ReturnSelf : NSObject{    @public    int _age;}- (ReturnSelf*) grow;@end@implementation ReturnSelf- (ReturnSelf*) grow{    _age++;    // return self,返回調用該方法的對象    return self;}@endint main(int argc , char * argv[]){    @autoreleasepool{        ReturnSelf* rt = [[ReturnSelf alloc] init];        //可以連續調用同一個方法        [[[rt grow] grow] grow];        NSLog(@rt的_age成員變數的值是:%d , rt->_age);    }}

說明:使用 self 作為方法的傳回值可以使代碼更加簡潔,但可能造成實際意義的模糊。

id 類型

id 類型可以代表所有對象的類型。任意類的對象都可賦值給 id 類型的變數。
通過 id 類型的變數來調用方法時,objective-c 將會執行動態綁定。動態綁定:objective-c 將會跟蹤對象所屬的類,會在運行時判斷該對象所屬的類,並在運行時確定需要動態調用的方法,而不是在編譯時間確定要調用的方法。
樣本程式:

#import #import FKPerson.hint main(int argc , char * argv[]) {    @autoreleasepool{        // 定義id類型的變數,並將FKPerson對象賦給該變數        id p = [[FKPerson alloc] init];        // 使用p變數來調用say:方法。        // 程式將在運行時執行動態綁定,因此實際執行FKPerson對象的say:方法        [p say: @你好,瘋狂iOS講義];    }}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.