В Objective C, как узнать тип возвращаемого значения метода через отражение? - PullRequest
4 голосов
/ 16 сентября 2011
@interface Foo : NSObject {
}

- (Bar)bar;

Во время выполнения, учитывая [класс Foo], как мы узнаем тип возврата всех методов, которые имеет Foo?

Я некоторое время изучал API-интерфейс Objective-C; насколько я могу судить, нет способа получить возвращаемый тип (то есть класс) метода или свойства. Похоже, это серьезное упущение в любом API рефлексии.

Ответы [ 2 ]

10 голосов
/ 16 сентября 2011

Вы можете использовать функции времени выполнения Objective C:

Method class_getClassMethod(Class aClass, SEL aSelector)
void method_getReturnType(Method method, char *dst, size_t dst_len)

Ссылка времени выполнения Objective C

Прежде всего, получите объект метода, используя class_getClassMethod

Method m = class_getClassMethod( [ SomeClass class ], @selector( someMethod ) );

Затем запрашивает тип возврата, используя method_getReturnType:

char ret[ 256 ];
method_getReturnType( m, ret, 256 );
NSLog( @"Return type: %s", ret );
4 голосов
/ 16 сентября 2011

Вы можете указать основную информацию, например, какой это тип C, но вы не можете различить различные типы экземпляров (или классы) по типу возвращаемого значения.

Objective-C никогда не разрабатывался и не предназначался для такого уровня отражения. Главным образом потому, что это значительно увеличило бы размер исполняемых файлов (все метаданные), и поддержка полного самоанализа метаданных аргумента / возвращаемого типа для всех типов C - думаю, типов C ++ - была бы невероятно сложной.

Уже были случаи, когда метаданные, связанные с параметризацией методов, измерялись на несколько порядков больше, чем сгенерированный код при передаче объектов C ++ в методы Objective-C (буквально - МБ для метаданных для одного вызов метода).

<Ч />

Пример относительно простого типа в форме метаданных аргумента / возвращаемого типа:

{CGRect={CGPoint=dd}{CGSize=dd}}96@0:8@16{CGRect={CGPoint=dd}{CGSize=dd}}24{CGRect={CGPoint=dd}{CGSize=dd}}56q88

И особенно вопиющий пример из WebKit:

^ {Документ = ^^? ^^? Я ^ {ContainerNode} {Слабое = ^ {JSValue}} ^ {Документ} ^ {Узел} ^ {Узел} ^ {RenderObject} Я ^ {Узел} ^ {Узел } ^ {TreeScope} {DocumentOrderedMap = {HashMap, WTF :: HashTraits, WTF :: HashTraits

= {HashTable, WTF :: PairFirstExtractor , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits , WTF :: HashTraits = ^ {Пара} IIIi}} {HashCountedSet, WTF :: HashTraits = {HashMap, WTF :: HashTraits, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits , WTF :: HashTraits = ^ {Пара} IIIi}}}} {DocumentOrderedMap = {HashMap, WTF :: HashTraits, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits , WTF :: HashTraits = ^ {Пара} IIIi}} {HashCountedSet, WTF :: HashTraits = {HashMap, WTF :: HashTraits, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits , WTF :: HashTraits = ^ {Пара} IIIi}}}} I ^^? {RefPtr = ^ {SecurityOrigin}} {HashSet, WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {MessagePort} IIIi}} {HashMap, WTF :: HashTraits, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits>, WTF :: HashTraits = ^ {Пара} IIIi}} {BB HashMap, WTF :: HashTraits, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor>, WTF :: IntHash, WTF :: PairHashTraits, WTF :: HashTraits>, WTF :: HashTraits = ^ {} Пара IIII}} В {OwnPtr, 0ul> = ^ {Vector, 0ul>}} {RefPtr = ^ {DatabaseThread}} Bi {OwnPtr = ^ {CSSStyleSelector}} BB {RefPtr = ^ {CSSPrimitiveValueCache}} ^ {Рамка} {OwnPtr = ^ {CachedResourceLoader}} {RefPtr = ^ {DocumentParser}} В {KURL = {String = {RefPtr = ^ {StringImpl}}} b1b1iiiiiiiiii} {KURL = {String = {RefPtr = ^ {StringImpl}}} b1b1iiiiiiiiii} {KURL = {String = {RefPtr = ^ {StringImpl}}} b1b1iiiiiiiiii} {KURL = {String = {RefPtr = ^ {StringImpl}}} b1b1iiiiiiiiii} {KURL = {String = {RefPtr = ^ {StringImpl}}} b1b1iiiiiiiiii} {String = {RefPtr = ^ {StringImpl }}} {String = {RefPtr = ^ {StringImpl}}} {RefPtr = ^ {DocumentType}} {OwnPtr = ^ {DOMImplementation}} iBiB {RefPtr = ^ {CSSStyleSheet}} {RefPtr = ^ {CSSStyleSheet}} {RefPtr = ^ {CSSStyleSheet}} {OwnPtr, 0ul> = ^ {Vector, 0ul>}} BBBBiB {color = IB} {RefPtr = ^ {Node}} {RefPtr = ^ {Node}} {RefPtr = ^ {Node}} {RefPtr = ^ {Элемент}} Q {HashSet , WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {NodeIterator} IIIi}} {HashSet, WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {Range} ииии}} S {RefPtr = ^ {StyleSheetList}} {ListHashSet = {* в hashTable 1016 *, WTF :: ListHashSetNode , WTF :: IdentityExtractor *>, WTF :: ListHashSetNodeHashFunctions , WTF :: HashTraits *>, WTF :: HashTraits *> = ^^ {ListHashSetNode} IIII} ^ {ListHashSetNode} ^ {ListHashSetNode} {OwnPtr = ^ {ListHashSetNodeAllocator}}} {ListHashSet = {* 1018 в hashTable *, WTF :: ListHashSetNode , WTF :: IdentityExtractor *>, WTF :: ListHashSetNodeHashFunctions , WTF :: HashTraits *>, WTF :: HashTraits *> = ^^ {ListHashSetNode} IIII} ^ {ListHashSetNode} ^ {ListHashSetNode} {OwnPtr = ^ {ListHashSetNodeAllocator}}} {ListHashSet= {* 1020 в hashTable *, WTF :: ListHashSetNode , WTF :: IdentityExtractor *>, WTF :: ListHashSetNodeHashFunctions , WTF :: HashTraits *>, WTF :: HashTraits *> = ^^ {ListHashSetNode} IIII} ^ {ListHashSetNode} ^ {ListHashSetNode} {OwnPtr = ^ {ListHashSetNodeAllocator}}} {HashMap, WebCore :: FormElementKeyHash, WebCore :: FormElementKeyHashTraits, WTF :: HashTraits> = {HashTable , WTF :: PairFirstExtractor> , WebCore :: FormElementKeyHash, WTF :: PairHashTraits> , WebCore :: FormElementKeyHashTraits> = ^ {пара } Ииии}} {color = IB} {color = IB} {color = IB} {String = {RefPtr = ^ {StringImpl}}} {String = {RefPtr = ^ {StringImpl}}} {BBiB Timer = ^^? DDII ^ {Документ} {? = ^ д}} BBBBBBBBBBBBBBBBBI {StringWithDirection = {String = {RefPtr = ^ {StringImpl}}} я} {StringWithDirection = {String = {RefPtr = ^ {StringImpl}}} я} B {RefPtr = ^ {Элемент}} {OwnPtr = ^ {RenderArena}} ^ {AXObjectCache} {OwnPtr = ^ {DocumentMarkerController}} {Таймер = ^^? DDII ^ {Документ} {? = ^ д}} ^ {Элемент} {B RefPtr = ^ {SerializedScriptValue}} дБи {OwnPtr = ^ {ScriptRunner}} {OwnPtr = ^ {TransformSource}} {RefPtr = ^ {Документ}} I {String = {RefPtr = ^ {StringImpl}}} {String = {RefPtr = ^ {StringImpl}}} B {String = {RefPtr = ^ {StringImpl}}} ^ {RenderObject} {RefPtr = ^ {TextResourceDecoder}} I {CheckedRadioButtons = {OwnPtr, WTF :: HashTraits, WTF :: HashTraits> = ^ {HashMap, WTF :: HashTraits, WTF :: HashTraits }}} {FixedArray = [10 {CollectionCache = Q ^ {Элемент} {IIi HashMap, ВТФ :: PtrHash, ВТФ :: HashTraits, WTF :: HashTraits *> = {HashTable, станд :: пара *>, WTF :: PairFirstExtractor *> , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits *> , WTF :: HashTraits = ^ {Пара *>} IIIi}} {HashMap, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits *> = {HashTable, станд :: пара *>, WTF :: PairFirstExtractor *> , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits *> , WTF :: HashTraits = ^ {Пара *>} ииии}} BB}]} {FixedArray, WTF :: HashTraits, WTF :: HashTraits , 2ul> = [2 {HashMap, WTF :: HashTraits, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor , WTF :: PtrHash, WTF :: PairHashTraits, WTF :: HashTraits , WTF :: HashTraits = ^ {Пара} ииии}}]} {RefPtr = ^ {XPathEvaluator}} {OwnPtr = ^ {SVGDocumentExtensions}} {Vector = Q {VectorBuffer = ^ {DashboardRegionValue} Q}} {BB HashMap, WTF :: StringHash, WTF :: HashTraits, WTF :: HashTraits

= {HashTable , WTF :: PairFirstExtractor> , WTF :: StringHash, WTF :: PairHashTraits, WTF :: HashTraits> , WTF :: HashTraits = ^ {Пара }}} IIII BB [1 {IconURL = I {KURL = {String = {RefPtr = ^ {StringImpl}}}}} b1b1iiiiiiiiii] {HashSet, WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {Элемент} IIIi}} {HashSet, WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {Элемент} IIIi}} {HashSet, WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {Элемент} IIIi}} {HashMap, WTF :: HashTraits = {HashTable, WTF :: PairFirstExtractor , WTF :: CaseFoldingHash, WTF :: PairHashTraits, WTF :: HashTraits>, WTF :: HashTraits = ^ {} Пара IIIi}} {BBBBBBB RefPtr = ^ {EventQueue}} {RefPtr = ^ {DocumentWeakReference}} {HashSet, WTF :: HashTraits = {В hashTable, WTF :: PtrHash, WTF :: HashTraits, WTF :: HashTraits = ^^ {MediaCanStartListener} IIII}} {QualifiedName = ^ {QualifiedNameImpl}} В {RefPtr = ^ {Элемент}} ^ {RenderFullScreen} {Таймер = ^^? DDII ^ {Документ} {? = ^ Д}} {Deque , 0ul> = QQ {VectorBuffer, 0ul> = ^ {RefPtr}}} В Б {IntRect = {IntPoint = б} {IntSize = б}} {RefPtr = ^ {RenderStyle}} I {Таймер = ^^? DDII ^ {Документ} {= ^ д?}} {ViewportArguments = FFFFFFF} {BB DocumentTiming = DDDDD} {RefPtr = ^ {MediaQueryMatcher}} {БИИ RefPtr = ^ {ContentSecurityPolicy}}} 16 @ 0: 8

...