【Objective-C】07-自訂構造方法和description方法

來源:互聯網
上載者:User

標籤:

  • 知識回顧
  • 一、自訂構造方法
  • 二、description方法

說明:這個Objective-C專題,是學習iOS開發的前奏,也為了讓有物件導向語言開發經驗的程式員,能夠快速上手Objective-C。如果你還沒有編程經驗,或者對Objective-C、iOS開發不感興趣,請忽略。學習本專題之前,建議先學習C語言專題。

回到頂部知識回顧

在第5講中已經介紹了如何定義類和建立並初始化對象,比如有Student這個類

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

 

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

 

3.在main函數中建立一個Student對象
 1 #import "Student.h" 2  3 int main(int argc, const char * argv[]) 4 { 5  6     @autoreleasepool { 7         Student *stu = [[Student alloc] init]; 8          9         stu.age = 10;10         11         [stu release];12     }13     return 0;14 }

* 在第7行調用Student的alloc方法分配記憶體,然後再調用init方法初始化對象

* 像init這樣用來初始化對象的方法,我們可以稱為"構造方法"

 

回到頂部一、自訂構造方法

預設的構造方法,也就是init方法,它是不接收任何參數的。因此,在實際開發中,為了方便,會經常自訂構造方法。

接下來,自訂一個構造方法,可以傳入一個age參數來初始化Student對象

1.在Student.h中添加方法聲明
- (id)initWithAge:(int)age;

* 構造方法的方法名一般都會以init開頭,傳回值跟init方法一樣為id類型,id可以代表任何OC對象

* 這個構造方法接收一個int類型的age參數,目的是在初始化Student對象時,順便設定成員變數_age的值

 

2.在Student.m中實現構造方法
1 - (id)initWithAge:(int)age {2     self = [super init];3     if (self != nil) {4         _age = age;5     }6     return self;7 }

* 跟Java一樣,構造方法內部首先要調用父類的構造方法,在第2行調用了父類的init方法,它會返回初始化好的Student對象,這裡把傳回值賦值給了self,self代表Student對象本身

* 第3~5行的意思是:如果self不為nil,也就是初始化成功,就給成員變數_age進行賦值

* 最後返回初始化過後的self,整個構造方法就結束了

 

3.簡化構造方法

由於C語言和OC的文法特性,我們可以對構造方法進行簡化,先簡化第3行

1 - (id)initWithAge:(int)age {2     self = [super init];3     if (self) {4         _age = age;5     }6     return self;7 }

* 第3行的 if(self) 跟 if(self!=nil) 是等價的

* 還可以將第2、3行合并,繼續簡化

1 - (id)initWithAge:(int)age {2     if ( self = [super init] ) {3         _age = age;4     }5     return self;6 }

* 第2行的總體意思是:先調用父類的構造方法init,然後將傳回值賦值給self,接著判斷self是否為nil

* 以後的構造方法都這樣寫了

 

4.調用構造方法
1 Student *stu = [[Student alloc] initWithAge:10];2 3 NSLog(@"age is %i", stu.age);4 5 [stu release];

* 在第1行調用了構造方法initWithAge:,並傳入10作為參數,因此Student對象的成員變數_age會變為10

* 在第3行列印Student的成員變數_age,列印結果:

2013-04-19 21:36:47.880 構造方法[448:303] age is 10

 

回到頂部二、description方法1.NSLog回顧

眾所周知,我們可以用NSLog函數來輸出字串和一些基本資料類

1 int age = 11;2 NSLog(@"age is %i", age);

* 第2行的%i代表會輸出一個整型資料,右邊的變數age會代替%i的位置進行輸出

* 輸出結果:

2013-04-19 21:43:47.674 構造方法[483:303] age is 11

 

2.NSLog輸出OC對象

其實,除了可以輸出基礎資料型別 (Elementary Data Type),NSLog函數還可以輸出任何OC對象

1 Student *stu = [[Student alloc] initWithAge:10];2 3 NSLog(@"%@", stu);4 5 [stu release];

* 在第3行用NSLog函數輸出stu對象,注意左邊的格式符%@,以後想輸出OC對象,就得用%@這個格式符

* NSLog函數一旦發現用%@輸出某個OC對象時,就會調用這個對象的description方法(這個方法傳回值是NSString類型,是OC中的字串類型),並且將description方法返回的字串代替%@的位置進行輸出

* description方法的預設實現是返回這樣的格式:<類名: 對象的記憶體位址>,因此上面代碼的輸出結果為:

2013-04-19 21:46:49.896 構造方法[492:303] <Student: 0x100109910>

Student是類名,0x100109910是對象的記憶體位址

* 注意了,%@只能用於輸出OC對象,不能輸出結構體等其他類型

* 有Java開發經驗的人應該能感受到OC中的description方法就是Java中的toString方法

 

3.重寫description方法

description方法的預設實現是返回類名和對象的記憶體位址,這樣的話,使用NSLog輸出OC對象,意義就不是很大,因為我們並不關心對象的記憶體位址,比較關心的是對象內部的一些成變數的值。因此,會經常重寫description方法,覆蓋description方法的預設實現

比如,重寫Student的description方法,返回成員變數_age的值

1 - (NSString *)description {2     return [NSString stringWithFormat:@"age=%i", _age];3 }

* 在第2行調用了NSString這個類的靜態方法stringWithFormat初始化一個字串對象,並返回這個字串

* 如果你會使用NSLog的話,那就應該能理解第2行的方法參數是什麼意思了

* 假如_age是10,那麼description方法返回的字串就是@"age=10"

* 可能有人會覺得奇怪,之前建立的Student對象是需要釋放的,為什麼這裡建立的字串對象不用釋放?要想徹底明白這個問題,需要先瞭解OC的記憶體管理,這裡我們暫不做詳細討論,後面會有章節詳細討論記憶體管理。你可以先記住一個規則:一般情況下,靜態方法返回的對象,都不用手動釋放。

* 重寫完description方法後,再次執行下面的代碼

1 Student *stu = [[Student alloc] initWithAge:10];2 3 NSLog(@"%@", stu);4 5 [stu release];

輸出結果為:

2013-04-19 22:09:56.625 構造方法[531:303] age=10

 

4.description方法的陷阱

千萬不要在description方法中同時使用%@和self,下面的寫法是錯誤的:

1 - (NSString *)description {2     return [NSString stringWithFormat:@"%@", self];3 }

第2行同時使用了%@和self,代表要調用self的description方法,因此最終會導致程式陷入死迴圈,迴圈調用description方法

【Objective-C】07-自訂構造方法和description方法

聯繫我們

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