2010-03-20 9 views
18

कहो मैं अपने वर्ग हैवैरिएबल नाम से स्ट्रिंग प्राप्त करने के लिए वैसे भी?

@interface Person : NSObject { NSString *name; } 

मैं अपने वर्ग के भीतर

Person *person = [[Person alloc] init]; 
NSLog(@"Name of variable %s\n", _NameofVariable_(person->name)); 

जवाब के लिए धन्यवाद NSString के नाम प्राप्त करने की आवश्यकता है, यहाँ समाधान मैं उत्तर से आया है

//returns nil if property is not found 
-(NSString *)propertyName:(id)property { 
    unsigned int numIvars = 0; 
    NSString *key=nil; 
    Ivar * ivars = class_copyIvarList([self class], &numIvars); 
    for(int i = 0; i < numIvars; i++) { 
     Ivar thisIvar = ivars[i]; 
     if ((object_getIvar(self, thisIvar) == property)) { 
      key = [NSString stringWithUTF8String:ivar_getName(thisIvar)]; 
      break; 
     } 
    } 
    free(ivars); 
    return key; 
} 
+0

आप भी 'मुक्त (ivars)', वरना आप सरणी रिसाव जाएगा चाहिए। –

+0

अच्छी पकड़, इसे प्रतिबिंबित करने के लिए अपडेट किया गया। – hacksignal

+0

क्या यह कक्षा में किसी भी संपत्ति का पहला नाम वापस नहीं करेगा जो आपके द्वारा पारित मूल्य से मेल खाता है? उदाहरण: https://gist.github.com/robskillington/684796bae2dd95592919 – rob

उत्तर

4

आप Objective-C runtime API समारोह class_copyIvarList के साथ एक वर्ग के उदाहरण चर के नाम मिल सकता है। हालांकि, यह शामिल है, शायद ही कभी किया गया है और लगभग कुछ हासिल करने का सबसे अच्छा तरीका कभी नहीं है। यदि आपके पास जिज्ञासा की तुलना में दिमाग में अधिक विशिष्ट लक्ष्य है, तो उद्देश्य-सी में इसे पूरा करने के तरीके के बारे में पूछना एक अच्छा विचार हो सकता है।

इसके अलावा, आकस्मिक रूप से, person.name उद्देश्य-सी में एक आवृत्ति चर निर्दिष्ट नहीं करता है - यह एक संपत्ति कॉल है। आवृत्ति चर person->name होगा।

+0

मैं तुम्हें उदाहरण चर कि जिस तरह से यहां पहुंच सकता है पता नहीं था। शायद इसका कभी भी उपयोग नहीं करेंगे, लेकिन जानना अच्छा होगा। –

+0

@ ब्रैंडन आप ऐसा कर सकते हैं क्योंकि उद्देश्य-सी ऑब्जेक्ट्स वास्तव में केवल structs हैं। :) –

+0

@Dave, रवींद्र! –

0

व्यक्ति वस्तु वर्ग के एक संपत्ति के रूप में सामने आ रहा है, तो आप प्राप्त करने के लिए उपयोग कर सकते हैं objc_msgSend मूल्य।

इसलिए, यदि आप

[object person] 

उपयोग करने वाला व्यक्ति यहां पहुंच सकता है आप भी

objc_msgSend(object, "person") 

संदेश के बारे में अधिक जानकारी के लिए कैसे तरीकों के तर्क पारित करने के लिए, को देखने के Objective-C Runtime Programming Guide section on Messaging

सहित भेजने कर सकता है
2

आप पूर्वप्रक्रमक stringification और स्ट्रिंग twiddling का एक सा इस्तेमाल कर सकते हैं:

NSUInteger lastIndexAfter(NSUInteger start, NSString *sub, NSString *str) { 
    NSRange found = [str rangeOfString:sub options:NSBackwardsSearch]; 
    if(found.location != NSNotFound) { 
     NSUInteger newStart = NSMaxRange(found); 
     if(newStart > start) 
      return newStart; 
    } 
    return start; 
} 

NSString *lastMember(NSString *fullName) { 
    if(!fullName) return nil; 

    NSUInteger start = 0; 
    start = lastIndexAfter(start, @".", fullName); 
    start = lastIndexAfter(start, @"->", fullName); 

    return [fullName substringFromIndex: start]; 
} 

#define NSStringify(v) (@#v) 
#define _NameofVariable_(v) lastMember(NSStringify(v)) 
33

के रूप में आसान के रूप में

#define VariableName(arg) (@""#arg)

तो फिर तुम कार्य करें:

NSObject *obj; 
NSString *str = VariableName(obj); 
NSLog(@"STR %@", str);//obj 
+0

क्या आप समझा सकते हैं कि यह कैसे काम करता है? :) –

+0

अब अप्रत्याशित था: डी धन्यवाद वैसे भी! –

+1

क्या किसी ने यह कोशिश की है?VariableName का प्रयास करें (here_s_a_random_string_that_s_not_a_var) यह संपत्ति या ivar को इसका नाम वापस करने का कोई तरीका नहीं है। यह आपको कुछ पाठ के आसपास @ "" टाइप करने से बचाने का एक तरीका है - और इसके बजाय आप VariableName() का उपयोग कर रहे हैं। या क्या मैं कुछ न कुछ भूल रहा हूं? – mahboudz

0

के रूप में निम्नलिखित काम करता है एक मैक्रो:

#define STRINGIZE(x) #x 
संबंधित मुद्दे

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