在目标C中,如何通过反射找出方法的返回类型? [英] In Objective C, how to find out the return type of a method via reflection?

查看:61
本文介绍了在目标C中,如何通过反射找出方法的返回类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@interface Foo : NSObject {
}

- (Bar)bar;

在运行时,给定[Foo类],我们如何找出Foo具有的所有方法的返回类型?

At runtime, given [Foo class], how do we find out the return type of all methods Foo has?

我已经研究Objective-C运行时API已有一段时间了;据我所知,没有办法获得方法或属性的返回类型(即类).在任何反射API中,这似乎都是一个严重的遗漏.

I have been studying the Objective-C runtime API for a while now; as far as I could tell, there is no way to get the return type (i.e. Class) of a method or a property. This seems to be a serious omission in any reflection API.

推荐答案

您可以告诉基本信息,例如C类型,但是您不能区分返回类型上的各种实例类型(或类).

You can tell basic information like what C type it is, but you can't differentiate between various instance types (or classes) on the return type.

Objective-C从未设计过,也不打算具有这种反射水平.主要是因为这样做会大大增加可执行文件(所有元数据)的大小,并支持所有C类型(认为C ++类型)的完整参数/返回类型元数据内省会非常复杂.

Objective-C was never designed nor intended to have that level of a reflection. Mostly because doing so would massively increase the size of the executables (all the metadata) and supporting full argument/return-type metadata introspection for all C types -- think C++ types -- would be incredibly complex.

已经存在以下情况:将C ++对象传递给Objective-C方法时,与方法参数化相关的元数据的度量值要比生成的代码大几个数量级(字面意义-单个元数据的MB方法调用).

Already, there have been cases where the metadata related to the parameterization of methods has measured in the orders of magnitude larger than the generated code when passing C++ objects to Objective-C methods (literally -- MBs for the metadata for a single method call).

以参数/返回类型元数据形式的相对简单类型的示例:

An example of a relatively simple type in argument/return-type metadata form:

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

还有一个来自WebKit的特别糟糕的例子:

And a particularly egregious example from the WebKit:

^ {Document = ^^?^^?i ^ {ContainerNode} {Weak = ^ {JSValue}} ^ {Document} ^ {Node} ^ {Node} ^ {RenderObject} I ^ {Node} ^ {Node } ^ {TreeScope} {DocumentOrderedMap = {HashMap,WTF :: HashTraits,WTF :: HashTraits

^{Document=^^?^^?i^{ContainerNode}{Weak=^{JSValue}}^{Document}^{Node}^{Node}^{RenderObject}I^{Node}^{Node}^{TreeScope}{DocumentOrderedMap={HashMap,WTF::HashTraits,WTF::HashTraits

= {HashTable,WTF :: PairFirstExtractor ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits ,WTF :: HashTraits = ^ {pair} iiii}} {HashCountedSet,WTF :: HashTraits = {HashMap,WTF :: HashTraits,WTF :: HashTraits = {HashTable,WTF :: PairFirstExtractor ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits ,WTF :: HashTraits = ^ {pair} iiii}}}} {DocumentOrderedMap = {HashMap,WTF :: HashTraits,WTF :: HashTraits = {HashTable,WTF :: PairFirstExtractor ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits ,WTF :: HashTraits = ^ {pair} iiii}} {HashCountedSet,WTF :: HashTraits = {HashMap,WTF :: HashTraits,WTF :: HashTraits = {HashTable,WTF :: PairFirstExtractor ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits ,WTF :: HashTraits = ^ {pair} 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 = ^ {pair} iiii}} BB {HashMap,WTF :: HashTraits,WTF :: HashTraits = {HashTable,WTF :: PairFirstExtractor>,WTF :: IntHash,WTF :: PairHashTraits, WTF :: HashTraits>,WTF :: HashTraits = ^ {pair} iiii}} B {OwnPtr, 0ul> = ^ {Vector,0ul>}} {RefPtr = ^ {DatabaseThread}} Bi {OwnPtr = ^ {CSSStyleSelector}} BB {RefPtr = ^ {CSSPrimitiveValueCache}} ^ {Frame} {OwnPtr = ^ {CachedResourceLoader}} {RefPtr = ^ {DocumentParser}} B {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 = ^ {Element}} Q {HashSet ,WTF :: HashTraits = {HashTable,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits = ^^ {NodeIterator} iiii}} {HashSet,WTF :: HashTraits = {HashTable,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits = ^^ {Range} iiii}} S {RefPtr = ^ {StyleSheetList}} {ListHashSet = {HashTable ,WTF :: ListHashSetNode ,WTF :: IdentityExtractor *>,WTF :: ListHashSetNodeHashFunctions ,WTF :: HashTraits *>,WTF :: HashTraits *> = ^^ {ListHashSetNode} iiii} ^ {ListHashSetNode} ^ {ListHashSetNode} {OwnPtr = ^ {ListHashSetNodeAllocator}}} {ListHashSet = {HashTable ,WTF :: ListHashSetNode ,WTF :: IdentityExtractor *>,WTF :: ListHashSetNodeHashFunctions ,WTF :: HashTraits *>,WTF :: HashTraits *> = ^^ {ListHashSetNode} iiii} ^ {ListHashSetNode} ^ {ListHashSetNode} {OwnPtr = ^ {ListHashSetNodeAllocator}}} {ListHashSet = {HashTable ,WTF :: ListHashSetNode ,WTF :: IdentityExtractor *>,WTF :: ListHashSetNodeHashFunctions ,WTF :: HashTraits *>,WTF :: HashTraits *> = ^^ {ListHashSetNode} iiii} ^ {ListHashSetNode} ^ {ListHashSetNode} {OwnPtr = ^ {ListHashSetNodeAllocator}}} {HashMap,WebCore :: FormElementKeyHash,WebCore :: FormElementKeyHashTraits,WTF :: HashTraits> = {哈希表 ,WTF :: PairFirstExtractor> ,WebCore :: FormElementKeyHash,WTF :: PairHashTraits> ,WebCore :: FormElementKeyHashTraits> = ^ {pair } iiii}} {Color = IB} {Color = IB} {Color = IB} {String = {RefPtr = ^ {StringImpl}}} {String = {RefPtr = ^ {StringImpl}}} BBiB {Timer = ^^? ddiI ^ {Document} {?= ^ q}} BBBBBBBBBBBBBBBBBI {StringWithDirection = {String = {RefPtr = ^ {StringImpl}}} i} {StringWithDirection = {String = {RefPtr = ^ {StringImpl}}} i} B {RefPtr = ^ {Element}} {OwnPtr = ^ {RenderArena}} ^ {AXObjectCache} {OwnPtr = ^ {DocumentMarkerController}} {Timer = ^^?ddiI ^ {Document} {?= ^ q}} ^ {Element} B { RefPtr = ^ {SerializedScriptValue}} dBi {OwnPtr = ^ {ScriptRunner}} {OwnPtr = ^ {TransformSource}} {RefPtr = ^ {Document}} 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 ^ {Element} IIi {HashMap,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits *> = {HashTable,std :: pair *>,WTF :: PairFirstExtractor *> ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits *> ,WTF :: HashTraits = ^ {pair *>} iiii}} {HashMap,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits *> = {HashTable,std :: pair *>,WTF :: PairFirstExtractor *> ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits *> ,WTF :: HashTraits = ^ {pair *>} iiii}} BB}]} {FixedArray, WTF :: HashTraits, WTF :: HashTraits ,2ul> = [2 {HashMap,WTF :: HashTraits,WTF :: HashTraits = {HashTable,WTF :: PairFirstExtractor ,WTF :: PtrHash,WTF :: PairHashTraits, WTF :: HashTraits ,WTF :: HashTraits = ^ {pair} iiii}}}} {RefPtr = ^ {XPathEvaluator}} {OwnPtr = ^ {SVGDocumentExtensions}} {Vector = Q {VectorBuffer = ^ {DashboardRegionValue} Q}} BB {HashMap,WTF :: StringHash,WTF :: HashTraits,WTF :: HashTraits

={HashTable,WTF::PairFirstExtractor ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits ,WTF::HashTraits =^{pair}iiii}}{HashCountedSet,WTF::HashTraits ={HashMap,WTF::HashTraits,WTF::HashTraits ={HashTable,WTF::PairFirstExtractor ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits ,WTF::HashTraits =^{pair}iiii}}}}{DocumentOrderedMap={HashMap,WTF::HashTraits,WTF::HashTraits ={HashTable,WTF::PairFirstExtractor ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits ,WTF::HashTraits =^{pair}iiii}}{HashCountedSet,WTF::HashTraits ={HashMap,WTF::HashTraits,WTF::HashTraits ={HashTable,WTF::PairFirstExtractor ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits ,WTF::HashTraits =^{pair}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 =^{pair}iiii}}BB{HashMap,WTF::HashTraits,WTF::HashTraits ={HashTable,WTF::PairFirstExtractor >,WTF::IntHash,WTF::PairHashTraits, WTF::HashTraits >,WTF::HashTraits =^{pair}iiii}}B{OwnPtr, 0ul> =^{Vector,0ul>}}{RefPtr=^{DatabaseThread}}Bi{OwnPtr=^{CSSStyleSelector}}BB{RefPtr=^{CSSPrimitiveValueCache}}^{Frame}{OwnPtr=^{CachedResourceLoader}}{RefPtr=^{DocumentParser}}B{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=^{Element}}Q{HashSet,WTF::HashTraits ={HashTable,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits =^^{NodeIterator}iiii}}{HashSet,WTF::HashTraits ={HashTable,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits =^^{Range}iiii}}S{RefPtr=^{StyleSheetList}}{ListHashSet ={HashTable,WTF::ListHashSetNode,WTF::IdentityExtractor*>,WTF::ListHashSetNodeHashFunctions ,WTF::HashTraits*>,WTF::HashTraits*> =^^{ListHashSetNode}iiii}^{ListHashSetNode}^{ListHashSetNode}{OwnPtr =^{ListHashSetNodeAllocator}}}{ListHashSet ={HashTable,WTF::ListHashSetNode,WTF::IdentityExtractor*>,WTF::ListHashSetNodeHashFunctions ,WTF::HashTraits*>,WTF::HashTraits*> =^^{ListHashSetNode}iiii}^{ListHashSetNode}^{ListHashSetNode}{OwnPtr =^{ListHashSetNodeAllocator}}}{ListHashSet ={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>=^{pair }iiii}}{Color=IB}{Color=IB}{Color=IB}{String={RefPtr=^{StringImpl}}}{String={RefPtr=^{StringImpl}}}BBiB{Timer=^^?ddiI^{Document}{?=^q}}BBBBBBBBBBBBBBBBBI{StringWithDirection={String={RefPtr=^{StringImpl}}}i}{StringWithDirection={String={RefPtr=^{StringImpl}}}i}B{RefPtr=^{Element}}{OwnPtr=^{RenderArena}}^{AXObjectCache}{OwnPtr=^{DocumentMarkerController}}{Timer=^^?ddiI^{Document}{?=^q}}^{Element}B{RefPtr=^{SerializedScriptValue}}dBi{OwnPtr=^{ScriptRunner}}{OwnPtr=^{TransformSource}}{RefPtr=^{Document}}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^{Element}IIi{HashMap,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits*> ={HashTable,std::pair*>,WTF::PairFirstExtractor*> ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits*> ,WTF::HashTraits =^{pair*>}iiii}}{HashMap,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits*> ={HashTable,std::pair*>,WTF::PairFirstExtractor*> ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits*> ,WTF::HashTraits =^{pair*>}iiii}}BB}]}{FixedArray, WTF::HashTraits, WTF::HashTraits ,2ul>=[2{HashMap,WTF::HashTraits,WTF::HashTraits ={HashTable,WTF::PairFirstExtractor ,WTF::PtrHash,WTF::PairHashTraits, WTF::HashTraits ,WTF::HashTraits =^{pair}iiii}}]}{RefPtr=^{XPathEvaluator}}{OwnPtr=^{SVGDocumentExtensions}}{Vector=Q{VectorBuffer=^{DashboardRegionValue}Q}}BB{HashMap,WTF::StringHash,WTF::HashTraits,WTF::HashTraits

= {哈希表 ,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 = ^^ {Element} iiii}} {HashSet,WTF :: HashTraits = {HashTable,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits = ^^ {Element} iiii}} {HashSet,WTF :: HashTraits = {HashTable,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits = ^^ {Element} iiii}} {HashMap,WTF :: HashTraits = {HashTable,WTF :: PairFirstExtractor ,WTF :: CaseFoldingHash,WTF :: PairHashTraits, WTF :: HashTraits>,WTF :: HashTraits = ^ {pair} iiii}} BBBBBBB {RefPtr = ^ {EventQueue}} {RefPtr = ^ {DocumentWeakReference}} {HashSet,WTF :: HashTraits = {HashTable,WTF :: PtrHash,WTF :: HashTraits,WTF :: HashTraits = ^^ {MediaCanStartListener} iiii}} {QualifiedName = ^ {QualifiedNameImpl}} B {RefPtr = ^ {Element}} ^ {RenderFullScreen} {Timer = ^^?ddiI ^ {Document} {?= ^ q}} {Deque ,0ul> = QQ {VectorBuffer,0ul> = ^ {RefPtr} Q}} B {IntRect = {IntPoint = ii} {IntSize = ii}} {RefPtr = ^ {RenderStyle}} i {Timer = ^^?ddiI ^ {Document} {?= ^ q}} {ViewportArguments = fffffff} BB {DocumentTiming = ddddd} {RefPtr = ^ {MediaQueryMatcher}} BII {RefPtr = ^ {ContentSecurityPolicy}}} 16 @ 0:8

={HashTable ,WTF::PairFirstExtractor > ,WTF::StringHash,WTF::PairHashTraits, WTF::HashTraits > ,WTF::HashTraits =^{pair }iiii}}BB[1{IconURL=i{KURL={String={RefPtr=^{StringImpl}}}b1b1iiiiiiiiii}}]{HashSet,WTF::HashTraits ={HashTable,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits =^^{Element}iiii}}{HashSet,WTF::HashTraits ={HashTable,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits =^^{Element}iiii}}{HashSet,WTF::HashTraits ={HashTable,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits =^^{Element}iiii}}{HashMap,WTF::HashTraits ={HashTable,WTF::PairFirstExtractor ,WTF::CaseFoldingHash,WTF::PairHashTraits, WTF::HashTraits >,WTF::HashTraits =^{pair}iiii}}BBBBBBB{RefPtr=^{EventQueue}}{RefPtr=^{DocumentWeakReference}}{HashSet,WTF::HashTraits ={HashTable,WTF::PtrHash,WTF::HashTraits,WTF::HashTraits =^^{MediaCanStartListener}iiii}}{QualifiedName=^{QualifiedNameImpl}}B{RefPtr=^{Element}}^{RenderFullScreen}{Timer=^^?ddiI^{Document}{?=^q}}{Deque,0ul>=QQ{VectorBuffer,0ul>=^{RefPtr}Q}}B{IntRect={IntPoint=ii}{IntSize=ii}}{RefPtr=^{RenderStyle}}i{Timer=^^?ddiI^{Document}{?=^q}}{ViewportArguments=fffffff}BB{DocumentTiming=ddddd}{RefPtr=^{MediaQueryMatcher}}BII{RefPtr=^{ContentSecurityPolicy}}}16@0:8

这篇关于在目标C中,如何通过反射找出方法的返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆