問題發生於從WebAPI取得結果,以Dictionary操作,再轉換成對應的Object時,取一個屬性可能是Int或String時發生以下錯誤:
Fatal Exception: NSInvalidArgumentException -[NSTaggedPointerString stringValue]: unrecognized selector sent to instance 0xa000039312f31305
原程式如下:
// Profile.h
@interface Payment : NSObject
@property (strong,nonatomic) NSString* name;
@property (strong,nonatomic) NSString* display_date;
@end
@interface Profile : NSObject
@property (strong,nonatomic) NSString* id;
@property (strong,nonatomic) NSMutableArray<Payment*>* payments;
@end
// Profile.m
@implementation Payment
-(id)initWithDictionary:(NSDictionary*)dic{
self = [super init];
if (self) {
self.name = dic[@"name"];
self.display_date = dic[@"display_date"]; // exception occur!!!!
}
}
@end
@implementation Profile
-(id)initWithDictionary:(NSDictionary*)dic{
self = [super init];
if (self) {
self.id = dic[@"id"];
if (nil != dic[@"payments"]){
self.payments = [NSMutableArray array];
for(NSDictionary* subDic in dic[@"payments"]){
Payment* payment = [[Payment alloc] initWithDictionary:subDic];
}
}
}
}
return self;
}
@end
原本的問題是因為我在下面這行發生錯誤:
self.display_date = dic[@"display_date"]; // exception occur!!!!
查了一下發現,這個display_date可能回過來int或string,我原以為反正我用string都可以通吃,沒想到如果第一筆是int、第二筆是string時會發生錯誤
於是乎我把這行改成,取它的stringValue:
self.display_date = [dic[@"display_date"] stringValue]; // exception occur!!!!
沒想到這麼一轉,原本的問題解了,但又反過來,在第二筆時因為已經是string了,所以再轉會出錯…
好吧,那只好在轉換前先判斷能否轉換了
所以在取這種特別的欄位時,改用以下的方法取得:
-(NSString *)getDictValueWithKey:(NSString*)key fromDict(NSDictionary*):dict {
NSString * string;
if ([[dict objectForKey:key] respondsToSelector:@selector(stringValue)]) {
string = [[dict objectForKey:key] stringValue];
}
else {
string = [NSString stringWithString:[dict objectForKey:key]];
}
return string;
}
註:其實我在自己的開發環境是無法完美重現後面那個問題的,所以只能先預判這樣可能可以解決這個問題