標籤:
特別注意:
千萬不要在description方法中同時使用%@和self,同時使用了%@和self,代表要調用self的description方法,因此最終會導致程式陷入死迴圈,迴圈調用description方法
1.NSLog回顧
大家都知道,我們可以用NSLog函數來輸出字串和一些基本資料類
1 int age = 11;
2 NSLog( @" age is %d", age);
* 第2行的%d代表會輸出一個整型資料,右邊的變數age會代替%d的位置進行輸出
* 輸出結果:
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方法返回的字串代替%@的位置進行輸出
*上面代碼的輸出結果為:0x100109910>
Student是類名,0x100109910是對象的記憶體位址
例子:(沒有重寫OC中的description方法時)description方法的預設實現是返回這樣的格式:<類名: 對象的記憶體位址>
* 注意了,%@只能用於輸出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方法後,再次執行下面的代碼
Student *stu = [[Student alloc] initWithAge:10];
2
3 NSLog(@"%@", stu);
4
5 [stu release];
1輸出結果為:
age=10
4.description方法的陷阱
千萬不要在description方法中同時使用%@和self,下面的寫法是錯誤的:
- (NSString *)description {
2 return [NSString stringWithFormat:@"%@", self];
3 }
1第2行同時使用了%@和self,代表要調用self的description方法,因此最終會導致程式陷入死迴圈,迴圈調用description方法
什麼情況下才要重寫Objective-C中的description方法