2012-06-29 12 views
5

मेरे पास एक यूनिट टेस्ट में सरल NSManagedObject एस का एक गुच्छा है। उनके पास NSString * प्रकार की एक name विशेषता है। मैं हमेशा अपना NSManagedObject वही entityName और Class नाम देता हूं।मैं ivar का उद्देश्य-सी वर्ग कैसे प्राप्त करूं?

@interface FooTest : GHTestCase { 
Foo *foo; 
} 
@end 
@implementation FooTest 

- (void) setUp { 
    [super setUp]; 

    foo = [NSEntityDescription insertNewObjectForEntityForName:@"Foo" 
             inManagedObjectContext:managedObjectContext]; 
    foo.name = @"foo"; 
} 
@end 

foo के बाद से एक इवर है, मुझे लगता है मैं हड़पने के लिए एक मैक्रो लिखने के लिए सक्षम होना चाहिए लगता होगा:

मैं निम्नलिखित कोड एक इकाई परीक्षण स्थापित करने के लिए 30 बार लिखने के लिए होने से बचने के लिए चाहते हैं foo के प्रकार (Foo), और बनाने के लिए उपयोग मेरी Foo:

:

#define InsertManagedObjectByVariable(variable) \ 
do { \ 
variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; \ 
variable.name = (NSString *) CFSTR(#variable); 
} while(0) 

बहरहाल, यह बजना में निम्न चेतावनी का कारण बनता है

variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; 
                      ^
                  Expected expression 

मैं भी सोचा था कि मैं Ivar class_getInstanceVariable(Class cls, const char* name) से ऑब्जेक्टिव-सी क्रम IVar का उपयोग कर प्रकार निर्धारित करने की कोशिश कर सकते हैं, लेकिन ivar_getTypeEncoding से प्रकार एन्कोडिंग से केवल IVar प्रकार की जानकारी उपलब्ध id है, जो पर्याप्त नहीं है।

क्या कोई संकलन समय या रनटाइम पर IVar की प्रकार की जानकारी प्राप्त करने का तरीका सोच सकता है?

+1

यह जांचने से परे इसका परीक्षण नहीं किया गया है कि क्या यह संकलित करता है लेकिन क्या आप 'टाइपऑफ() 'ड्रॉप नहीं कर सकते और' [चर क्लास]' के साथ नहीं जा सकते? –

+0

नहीं, क्योंकि 'चर' शून्य है। –

उत्तर

6

मैंने एक ivar से कक्षा की जानकारी प्राप्त करने का प्रयास नहीं किया है, लेकिन मुझे पता है कि @property घोषणा कक्षा के बारे में जानकारी को एन्कोड करती है। उदाहरण के लिए, इस संपत्ति घोषणा: इस विशेषता स्ट्रिंग (property_getAttributes() का उपयोग कर लिया गया) में

@property (copy) NSString *normalString; 

परिणाम कार्यावधि में:

[email protected]"NSString",C,VnormalString 

मैं some open source parsing code इस जानकारी के लिए लिखा है।

एक बार जब आप वर्ग के नाम है, तो आप यह NSClassFromString() का उपयोग कर एक वास्तविक कक्षा वस्तु, और संदेश वहां से परिणाम में बदल सकते हैं।

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

+0

बहुत बढ़िया। मुझे पता था कि जब मैंने यह सवाल लिखा था कि आपको जवाब पता होगा। :) –

+1

बहुत ही रोचक चीजें। स्ट्रिंग के रूप में प्रकार को शामिल करना दस्तावेज नहीं है; क्या आपको पता चल गया कि इसे कब पेश किया गया था? –

+0

@RobNapier हम्म, वास्तव में कोई विचार नहीं है। जब तक मैंने कोशिश की है तब तक यह क्लैंग/ऑब्जेक्टिव-सी 2.0 में काम कर रहा है। शायद उत्पादन कोड के लिए इस पर निर्भर रहने का अच्छा विचार नहीं है, लेकिन इस तरह के परीक्षण समाधान के लिए बहुत मूल्यवान है। –

0

शायद मैं समझ सकता हूं कि आप क्या हासिल करने की कोशिश कर रहे हैं। iVar की कक्षा प्राप्त करने के लिए, क्या आप iVar की कक्षा विधि का उपयोग नहीं कर सकते?

चाहते:

NSString *aString = @"random string"; 
NSLog(@"%@",NSStringFromClass([aString class])); 
+2

यदि काम में मामला है, तो इवर का मूल्य शून्य है, तो काम नहीं करेगा। –

5

एक id एक id है। रनटाइम पर, सभी उद्देश्य-सी ऑब्जेक्ट्स का एक ही प्रकार होता है (objc_object)। यह ओबीजेसी की गतिशील प्रकृति में बंधे हैं। उदाहरण के लिए, कोई ऑब्जेक्ट रनटाइम पर कक्षाएं बदल सकता है, नए वर्ग बनाए जा सकते हैं, और कक्षा पदानुक्रम बदल सकता है। आप एक विशिष्ट उदाहरण से पूछ सकते हैं कि इसका प्रकार क्या है (क्योंकि यह objc_object में संग्रहीत है), लेकिन ऑब्जेक्ट के लिए पॉइंटर किसी ऑब्जेक्ट के लिए केवल एक पॉइंटर है। उससे भी कम: यह वास्तव में एक सी struct कि अतिरिक्त स्मृति अंत में आवंटित राशि का क्या होता है करने के लिए सिर्फ एक सूचक है (उपवर्ग ivars धारण करने के लिए)।

आपका मैक्रो दिलचस्प लगता है, लेकिन आपको संभवतः कक्षा नाम को दूसरे पैरामीटर के रूप में पास करने की आवश्यकता होगी।

+0

धन्यवाद। हां, मैंने अपने प्रश्न में यह रूपरेखा करने की कोशिश की। मुझे आशा है कि पागल सी प्रीप्रोसेसर कौशल वाले किसी व्यक्ति को यह दिखाई देगा और यह पता लगाएगा कि टाइपऑफ() को अभिव्यक्ति में कैसे चालू किया जाए। –

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

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