2012-02-13 14 views
9

मैं एक उद्देश्य-सी बेस क्लास बनाना चाहता हूं जो रनटाइम पर सभी गुणों (विभिन्न प्रकार के) पर एक ऑपरेशन करता है। चूंकि गुणों के नाम और प्रकार हमेशा ज्ञात नहीं होंगे, मैं ऐसा कुछ कैसे कर सकता हूं?रनटाइम पर सभी ऑब्जेक्ट गुणों के माध्यम से लूप

@implementation SomeBaseClass 

- (NSString *)checkAllProperties 
{ 
    for (property in properties) { 
     // Perform a check on the property 
    } 
} 

संपादित करें: यह एक कस्टम - (NSString *)description: ओवरराइड में विशेष रूप से उपयोगी होगा।

उत्तर

21

MVDS 'जवाब पर विस्तार करने के लिए, यहाँ एक छोटे से नमूना कार्यक्रम के माध्यम से पाश के लिए ऑब्जेक्टिव-सी क्रम एपीआई का उपयोग करता है है (इससे पहले कि मैं उसकी देखा यह लिखना शुरू किया) और एक कक्षा में प्रत्येक संपत्ति के बारे में प्रिंट जानकारी:

#import <Foundation/Foundation.h> 
#import <objc/runtime.h> 

@interface TestClass : NSObject 

@property (nonatomic, retain) NSString *firstName; 
@property (nonatomic, retain) NSString *lastName; 
@property (nonatomic) NSInteger *age; 

@end 

@implementation TestClass 

@synthesize firstName; 
@synthesize lastName; 
@synthesize age; 

@end 

int main(int argc, char *argv[]) { 
    @autoreleasepool { 
     unsigned int numberOfProperties = 0; 
     objc_property_t *propertyArray = class_copyPropertyList([TestClass class], &numberOfProperties); 

     for (NSUInteger i = 0; i < numberOfProperties; i++) 
     { 
      objc_property_t property = propertyArray[i]; 
      NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)]; 
      NSString *attributesString = [[NSString alloc] initWithUTF8String:property_getAttributes(property)]; 
      NSLog(@"Property %@ attributes: %@", name, attributesString); 
     } 
     free(propertyArray); 
    } 
} 

आउटपुट:

संपत्ति की आयु जिम्मेदार बताते हैं: टी^q, Vage
संपत्ति lastName जिम्मेदार बताते हैं: टी @ "NSString", &, एन, VlastName
संपत्ति firstName जिम्मेदार बताते हैं: टी @ "NSString", &, एन, VfirstName

ध्यान दें कि यह कार्यक्रम एआरसी के साथ संकलित करने की आवश्यकता है कामोत्तेजित।

+0

एक अच्छा अनुवर्ती प्रश्न यह होगा कि प्रत्येक गतिशील रूप से मूल्यों को कैसे वापस किया जाए ... मैं गतिशील रूप से एक एक्सेसर बनाने की सोच रहा हूं, लेकिन वाक्य रचनात्मक रूप से, मैं अभी भी इसे समझने की कोशिश कर रहा हूं। –

+1

कुछ तरीके हैं जो आप कर सकते हैं, लेकिन सबसे सरल सीवीसी का उपयोग करना होगा: 'id value = [self valueForKey: @" propertyName "]'। थोड़ा और जटिल हो जाता है जहां आपके पास आदिम (int, float, आदि) और ऑब्जेक्ट (एनएसएसटींग, आदि) दोनों प्रकार के रिटर्न प्रकार होते हैं, लेकिन बुनियादी आधार काम करेगा। –

+0

यह कोड नरक की तरह लीक – mvds

14

उपयोग

objc_property_t * class_copyPropertyList(Class cls, unsigned int *outCount) 

और कैसे इस वास्तव में क्या करने के लिए पर https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html पढ़ें।

कुछ कोड हो तुम जा रहे हैं:

#import <objc/runtime.h> 

unsigned int count=0; 
objc_property_t *props = class_copyPropertyList([self class],&count); 
for (int i=0;i<count;i++) 
{ 
    const char *name = property_getName(props[i]); 
    NSLog(@"property %d: %s",i,name); 
} 
+1

तारकीय। धातु के रनटाइम पागलपन के लिए बिल्कुल सही संसाधन। –

+0

बहुत बहुत धन्यवाद, अच्छा काम करता है, मैं रनटाइम पर एक ऑब्जेक्ट गुणों को अन्य में कैसे कॉपी करूं? –

+1

@PavanSaberjack 'valueForKey:' और 'setValue: forKey:' का उपयोग करके, जहां आपको नोटिस लेना होगा कि 'char * name' को किसी प्रकार के रूपांतरण के बिना ऑब्जेक्ट (यानी 'NSString') के रूप में उपयोग नहीं किया जा सकता है। – mvds

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