description基本概念
?
1.NSLog(@"%@", objectA);這會自動調用objectA的description方法來輸出ObjectA的描述信息.
2.description方法默認返回對象的描述信息(默認實現是返回類名和對象的內存地址)
3.description方法是基類NSObject 所帶的方法,因為其默認實現是返回類名和對象的內存地址, 這樣的話,使用NSLog輸出OC對象,意義就不是很大,因為我們并不關心對象的內存地址,比較關心的是對象內部的一些成變量的值。因此,會經常重寫description方法,覆蓋description方法 的默認實現
description重寫的方法
/**對象方法:當使用NSLog輸出該類的實例對象的時候調用*/
-(NSString *) description
{
return [NSString stringWithFormat:@"狗腿數:%d,狗眼數%d\n",_legNum,_eyeNum];
}
/**類方法:當使用NSLog輸出該類的類對象的時候調用*/
+(NSString *) description
{
return @"+開頭的description方法";
}
description陷阱
1.千萬不要在description方法中同時使用%@和self,下面的寫法是錯誤的
- (NSString *)description {
return [NSString stringWithFormat:@"%@", self];
};
2.同時使用了%@和self,代表要調用self的description方法,因此最終會導致程序陷入死循環,循 環調用description方法;
3.當[NSString stringWithFormat:@“%@”, self]; 使用它時,循壞調用,導致系統會發生運行時錯誤;
4.當該方法使用NSLog(“%@”,self) 時候, 系統做了相關的優化,循壞調用3次后就會自動退出.
@property?(nonatomic,?copy,?readonly)?NSString?*name;
@property?(nonatomic,?copy,?readonly)?NSString?*work;
- (id)initWithName:(NSString?*)name
????????????? work:(NSString?*)work;
@end
@implementation?LaoShiEr
- (id)initWithName:(NSString?*)name
????????????? work:(NSString?*)work
{
????if?((self?= [superinit])) {
????????_name?= [name?copy];
????????_work?= [work?copy];
??? }
????return?self;
}
- (NSString?*)description
{
????return?[NSStringstringWithFormat:@"<%@ : %p,\"%@ %@\">",[selfclass],self,_name,_work];
}
@end
按照上面的代碼來寫,輸出如下信息
LaoShiEr?*laoshi = [[LaoShiEralloc]
????????????????????????initWithName:@"laoshier"
????????????????????????work:@"coder"];
????NSLog(@"laoshier = %@",laoshi);
laoshier = <LaoShiEr : 0xb64bec0,"laoshier coder">
這樣就比之前所輸出得信息更加清楚了,也更為有用了。再description中輸出很多互不相同的信息的時候可以借助NSDictionary類的description方法。修改一下老師兒的description方法
- (NSString?*)description
{
????return?[NSStringstringWithFormat:@"<%@ : %p, %@>",[selfclass],self,@{@"name":_name,@"work":_work}];
}
再此輸出
laoshier = <LaoShiEr : 0xb677420, {
??? name = laoshier;
??? work = coder;
}>
debugDescription方法是開發者在調試器中以控制臺命令打印對象時才調用的。在NSObject類的默認實現中,此方法只是直接調用了description。以LaoShiEr為例,我們在創建實例所用的代碼后面插入斷點,然后通過調試器運行程序,暫停于此:并且po完成對象打印:
<LaoShiEr : 0xb7c4310, {
??? name = laoshier;
??? work = coder;
}>
當你不想把類名與指針地址這種額外內容放在普通的描述信息里,但是卻希望調試的時候能夠很方便地看到它們,在此情況下,就可以使用這種輸出方式來實現。- (NSString?*)description
{
????return?[NSStringstringWithFormat:@"<%@>",@{@"name":_name,@"work":_work}];
}
- (NSString?*)debugDescription
{
????return?[NSStringstringWithFormat:@"<%@ : %p, %@>",[selfclass],self,@{@"name":_name,@"work":_work}];
}