2012-01-06 13 views
6

यह देखते हुए कि मेरे पास method_copyReturnType() द्वारा लौटाए गए प्रकार का एक प्रकार है। जीसीसी के साथ दिए गए जीएनयू रनटाइम में objc_sizeof_type(), objc_alignof_type() और अन्य जैसे प्रकार के विनिर्देशक के साथ काम करने के लिए कई विधियां हैं।उद्देश्य-सी प्रकार विनिर्देशक की व्याख्या कैसे करें (उदा। Method_copyReturnType() द्वारा लौटाया गया है)?

ऐप्पल रनटाइम का उपयोग करते समय ऐसी कोई विधि नहीं होती है।

ऐप्पल रनटाइम का उपयोग करके के बिना किसी अन्य प्रकार के केस स्विच को लागू करने के लिए मैं एक प्रकार विनिर्देशक स्ट्रिंग (जैसे किसी प्रकार का आकार प्राप्त कर सकता हूं) की व्याख्या कैसे कर सकता हूं?

[अद्यतन]

मैं एप्पल फाउंडेशन उपयोग करने में सक्षम नहीं हूँ।

उत्तर

2

afaik, आपको उस जानकारी को अपनी बाइनरी में सेंकना होगा। बस एक फ़ंक्शन बनाएं जो संरचना में आकार और संरेखण देता है, आपको जिस प्रकार का समर्थन करना चाहिए, उसका समर्थन करता है, फिर जानकारी के लिए उस फ़ंक्शन (या क्लास विधि) को कॉल करें।

नीचे दिया गया कार्यक्रम आपको दिखाता है कि कई प्राइमेटिव केवल एक चरित्र हैं। तो फंक्शन के कार्यान्वयन का बड़ा हिस्सा एक स्विच हो सकता है।

static void test(SEL sel) { 
    Method method = class_getInstanceMethod([NSString class], sel); 

    const char* const type = method_copyReturnType(method); 

    printf("%s : %s\n", NSStringFromSelector(sel).UTF8String, type); 

    free((void*)type); 
} 

int main(int argc, char *argv[]) { 
    @autoreleasepool { 

     test(@selector(init)); 
     test(@selector(superclass)); 
     test(@selector(isEqual:)); 
     test(@selector(length)); 

     return 0; 
    } 
} 

और आप तो एक प्रारंभिक बिंदु के रूप में उपयोग कर सकते हैं:

typedef struct t_pair_alignof_sizeof { 
    size_t align; 
    size_t size; 
} t_pair_alignof_sizeof; 

static t_pair_alignof_sizeof MakeAlignOfSizeOf(size_t align, size_t size) { 
    t_pair_alignof_sizeof ret = {align, size}; 
    return ret; 
} 

static t_pair_alignof_sizeof test2(SEL sel) { 
    Method method = class_getInstanceMethod([NSString class], sel); 
    const char* const type = method_copyReturnType(method); 
    const size_t length = strlen(type); 

    if (1U == length) { 
     switch (type[0]) { 
      case '@' : 
       return MakeAlignOfSizeOf(__alignof__(id), sizeof(id)); 
      case '#' : 
       return MakeAlignOfSizeOf(__alignof__(Class), sizeof(Class)); 
      case 'c' : 
       return MakeAlignOfSizeOf(__alignof__(signed char), sizeof(signed char)); 
      ... 
+0

तो उत्तर है: इसे स्वयं लागू किए बिना ऐसा करने का कोई तरीका नहीं है। सही बात? –

+0

@ टिलो मैंने रनटाइम के साथ कुछ मूर्ख चीजें की हैं - मुझे कोई मुफ्त समाधान नहीं है, लेकिन मुझे पता है कि अगर आप जानते हैं कि आपको किस प्रकार का समर्थन करना चाहिए तो मेरे उत्तर में समाधान को आसानी से कार्यान्वित किया जा सकता है। बेशक, आप प्रतीक्षा कर सकते हैं और देख सकते हैं कि क्या आपको अधिक उचित उत्तर मिलता है या नहीं। – justin

+0

@ टिलो - इस – justin

5

मुझे विश्वास है कि आप NSGetSizeAndAlignment लिए देख रहे हैं:

वास्तविक आकार और की गठबंधन आकार प्राप्त करता एक एन्कोडेड प्रकार।

const char * NSGetSizeAndAlignment (
    const char *typePtr, 
    NSUInteger *sizep, 
    NSUInteger *alignp 
);

चर्चा
वास्तविक आकार और typePtr के प्रतिनिधित्व वाले पहले डेटा प्रकार के गठबंधन आकार प्राप्त और typePtr में अगले डेटा प्रकार की स्थिति के लिए एक सूचक देता है।

यह एक फाउंडेशन फ़ंक्शन है, बेस रनटाइम का हिस्सा नहीं है, शायद यही कारण है कि आपको यह नहीं मिला।

अद्यतन: यद्यपि आप शुरू में है कि आप Cocotron उपयोग कर रहे हैं का उल्लेख नहीं था, यह भी उपलब्ध नहीं है। आप कोकोट्रॉन फाउंडेशन में NSObjCRuntime.m में पा सकते हैं।

जाहिर है, यह आपके खुद को रोल करने से कहीं बेहतर है, क्योंकि आप एन्कोडिंग वर्णों को बदलने की संभावना नहीं होने पर संभावित रूप से अपने रनटाइम द्वारा उत्पन्न तारों को सही तरीके से संभालने पर भरोसा कर सकते हैं।

कुछ कारणों से, हालांकि, यह एक विधि हस्ताक्षर स्ट्रिंग के अंक तत्वों को संभालने में असमर्थ है (जो शायद स्मृति में ऑफसेट के साथ कुछ करने के लिए है)। This improved version, by Mike Ash ऐसा करेगा:

static const char *SizeAndAlignment(const char *str, NSUInteger *sizep, NSUInteger *alignp, int *len) 
{ 
    const char *out = NSGetSizeAndAlignment(str, sizep, alignp); 
    if(len) 
     *len = out - str; 
    while(isdigit(*out)) 
     out++; 
    return out; 
} 
+0

+1 अच्छा खोज, जोश – justin

+0

समस्या यह है कि मेरे पास ऐप्पल उत्पादों के लिए सामान्य पहुंच नहीं है क्योंकि यह केवल ऐप्पल उत्पादों के लिए मौजूद है :)। जिस परियोजना पर मैं काम कर रहा हूं वह कोकोट्रॉन (फाउंडेशन का विकल्प) है। तो मैं फाउंडेशन विधियों का उपयोग नहीं कर सकता। –

+0

@ टिलो: आप जिस ढांचे का उपयोग कर रहे हैं वह एक ** बहुत बड़ी स्थिति ** है जिसे आपको शायद शुरू करने के लिए अपने प्रश्न में शामिल करना चाहिए था। हालांकि, वही कार्य कोकोक्ट्रॉन में उपलब्ध है। मेरा संपादन देखें। –

संबंधित मुद्दे