【Objective-C基礎知識-05】關鍵字self、點文法

來源:互聯網
上載者:User

標籤:

一、傳統的get方法和set方法

  在Java中,我們可以通過"對象名.成員變數名"來訪問對象的公用成員變數,這個就稱為"點文法"。在正式學習OC的點文法之前,先來看一下傳統的get方法和set方法。定義一個Student類,擁有一個成員變數age和對應的get\set方法。

  Student.h

 1 #import <Foundation/Foundation.h> 2  3 @interface Student : NSObject { 4     int age; 5 } 6  7 - (void)setAge:(int)newAge; 8 - (int)age; 9 10 @end

  上面的代碼做了這樣的操作:

      (1) 在第4行定義了一個成員變數age,是@protected許可權的,所以外界不能直接存取它

    (2)在第7、8行分別聲明了age變數的set方法和get方法

  Student.m

 1 #import "Student.h" 2  3 @implementation Student 4  5 - (void)setAge:(int)newAge { 6     age = newAge; 7 } 8  9 - (int)age {10     return age;11 }12 13 @end

   上面的代碼做了這樣的操作:

    (1) 在第5行實現了set方法

    (2)在第9行實現了get方法

  main.m

    把定義好的Student類放到main函數中使用

#import <Foundation/Foundation.h>#import "Student.h"int main(int argc, const char * argv[]){    @autoreleasepool {        Student *stu = [[Student alloc] init];                // 設定age的值        [stu setAge:10];                // 取出age的值        int age = [stu age];                NSLog(@"age is %i", age);                [stu release];    }    return 0;}

  上面的代碼做了這樣的操作: 

    (1)在2行包含Student的標頭檔

    (2)在第7行建立Student對象,在第17行釋放Student對象

    (3)在第10行調用set方法設定age的值

    (4)在第13行調用get方法擷取age的值

    (5)在第15行輸出age的值,輸出結果如下:

2015-12-06 01:03:19.002 點文法[6164:303] age is 10

  這就是OC傳統的get方法和set方法的簡單使用,對初學者來說,這個文法比較奇怪,因為它的方法調用是用方括弧[ ]完成的。因此,OC最終引入了點文法。

 

二、使用點文法代替傳統的get方法和set方法

  上面示範了OC傳統get\set方法的簡單用法,接下來使用點文法來代替。

  前面main.m中main函數的代碼可以改為:

 1 int main(int argc, const char * argv[]) 2 { 3     @autoreleasepool { 4         Student *stu = [[Student alloc] init]; 5          6         // 設定age的值 7         stu.age = 10; // 等價於[stu setAge:10]; 8          9         // 取出age的值10         int age = stu.age; // 等價於int age = [stu age];11         12         NSLog(@"age is %i", age);13         14         [stu release];15     }16     return 0;17 }

  1.注意第7行代碼,把原來的[stu setAge:10]替換成了stu.age = 10。聽清楚了,這兩種寫法是完全等價的。即這裡的stu.age並不是代表直接存取stu對象的成員變數age,而是編譯器遇到stu.age = 10的時候會自動將代碼展開成[stu setAge:10]

  再說,如果是直接存取成員變數的話,OC中應該是這樣的文法:stu->age,而不是stu.age。

  2.注意第10行代碼,把原來的int age = [stu age]替換成了int age = stu.age。這兩種寫法又是完全等價的,stu.age並不是直接存取stu對象的成員變數age,而是編譯器遇到int age = stu.age的時候會自動將代碼展開成int age = [stu age]

  3.因此,OC中點文法的含義跟Java是完全不一樣的,OC點文法的本質是方法調用,不是直接存取成員變數。至於這個點文法代表的是get方法還是set方法,那就取決於你是取值還是設值,取值就是get方法(如第10行代碼),設值就是set方法(如第7行代碼)。 

 

  4.如果你想驗證點文法是不是方法調用的話,有很多方法。比如你可以在Student.m的set方法和get方法內部用NSLog加一些列印資訊,如果程式運行後有輸出列印資訊,說明的確是調用了get方法或者set方法

#import "Student.h"@implementation Student- (void)setAge:(int)newAge {    NSLog(@"調用了setAge方法");    age = newAge;}- (int)age {    NSLog(@"調用了age方法");    return age;}@end

 

三、點文法和self的陷阱

1  - (void)setAge:(int)newAge {2      self.age = newAge;3  }

  第2行中的self代表著當前調用setAge:方法的對象。但是第2行代碼是絕對錯誤的,會造成死迴圈。因為我在前面已經說過了,OC點文法的本質是方法調用,所以上面的代碼相當於:

1  - (void)setAge:(int)newAge {2      [self setAge:newAge];3  }

  很明顯,會造成迴圈調用setAge:方法,程式就這樣崩潰了

 

四、一點小建議

  如果是第一次接觸OC的點文法,你可能會真的以為stu.age的意思是直接存取stu對象的成員變數age。其實,有一部分原因是因為我這裡定義的Student類的成員變數名就叫做age。為了更好地區分點文法和成員變數訪問,一般我們定義的成員變數會以底線 _ 開頭。比如叫做 _age 。

  1.Student.h,注意第4行

 1 #import <Foundation/Foundation.h> 2  3 @interface Student : NSObject { 4     int _age; 5 } 6  7 - (void)setAge:(int)newAge; 8 - (int)age; 9 10 @end

  2.Student.m,注意第6行和第10行

 1 #import "Student.h" 2  3 @implementation Student 4  5 - (void)setAge:(int)newAge { 6     _age = newAge; 7 } 8  9 - (int)age {10     return _age;11 }12 13 @end

 

【Objective-C基礎知識-05】關鍵字self、點文法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.