この型判定がくせものでランタイム時に提供される情報(NSMethoSignatureなど)では引数/戻り値のクラスを知る方法を見つけることができなかった(オブジェクト=idであることしかわからなかった)。setterの場合は引数の型でそれが判断できるが getterの場合 Property List から取り出した NSData から判断するしかない。
と書いたが何のことはない、ランタイム関数を使えばプロパティのクラス名(文字列)が取得できるのでそれを使えばいい。
こんな感じ
- (NSString*)classNameForKey:(NSString*)key { NSString* className = nil; objc_property_t property = class_getProperty(self.target.class, key.UTF8String); const char* value = property_copyAttributeValue(property, "T"); if (value && value[0] == '@') { NSString* valueString = [NSString stringWithUTF8String:&value[1]]; className = [valueString stringByReplacingOccurrencesOfString:@"\"" withString:@""]; } return className; }
property_copyAttributeValue のキーは property_copyAttributeList()で取得した objc_property_attribute_t.key を見るとわかる。例えば NSString の場合はこんな感じ。
T: @"NSString" &: N: V: _stringValue属性 T の場合の値が型を表していてオブジェクト型の場合はタイプが @ でその後に "クラス名" が続く。プリミティブ型の場合、クラス名はつかない。
以下はintegerの場合
T: i N: V: _integerValue
上記メソッドを使う方法で LKUserDefaultsを修正した。これをもってVer1.0.0としてみた。
Responses
Leave a Response