Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Objective C, how to find out the return type of a method via reflection?

@interface Foo : NSObject {
}

- (Bar)bar;

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

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.

like image 205
Evil Nodoer Avatar asked Dec 10 '22 06:12

Evil Nodoer


2 Answers

You can use the Objective-C runtime functions:

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

Objective-C Runtime Reference

First of all, get the method object, using class_getClassMethod

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

Then, asks for the return type using method_getReturnType:

char ret[ 256 ];
method_getReturnType( m, ret, 256 );
NSLog( @"Return type: %s", ret );
like image 142
Macmade Avatar answered Dec 14 '22 22:12

Macmade


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 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.

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

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

={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

={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

like image 40
bbum Avatar answered Dec 15 '22 00:12

bbum