2012-02-13 19 views
9

Çalışma zamanında tüm özelliklerde (değişen türlerde) bir işlem gerçekleştiren bir Objective-C temel sınıfı oluşturmak istiyorum. Özelliklerin isimleri ve türleri her zaman bilinmeyeceğinden, böyle bir şeyi nasıl yapabilirim?Çalışma zamanında tüm nesne özelliklerinin içinden geçme

@implementation SomeBaseClass 

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

DÜZENLEME: Bu, özel bir - (NSString *)description: geçersiz kılma özellikle faydalı olacaktır.

cevap

21

MVDs' Yanıta genişletmek için, burada döngü Objective-C çalışma zamanı API'sini kullanan küçük örnek program (ben de onunkini görmeden bu yazmaya başladı) ve bir sınıftaki her özellik hakkında baskı bilgisi:

#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); 
    } 
} 

Çıktı:

Mülkiyet yaş niteliklerini T^q, Våge
Mülkiyet lastName niteliklerini: T @ "NSString", &, N, VlastName
Mülkiyet firstName niteliklerini: T @ "NSString", &, N, VfirstName

Not bu program ARC ile derlenmiş gerektiğini açık.

+0

İyi bir takip sorusu, dinamik olarak her birinin değerlerini nasıl döndüreceğimiz olurdu ... Dinamik olarak bir erişimci oluşturmayı düşünüyorum ama sözdizimsel olarak, bunu anlamaya çalışıyorum. –

+1

Bunu yapmanın birkaç yolu vardır, ancak en basit olanı KVC: 'id değeri = [self valueForKey: @" propertyName "]' dır. Hem ilkel (int, float, vb) hem de nesne (NSString, vs) dönüş türlerine sahip olduğunuzda biraz daha karmaşıklaşır, ancak temel önermeler işe yarayacaktır. –

+0

Bu kod cehennem – mvds

14

Kullanım

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

ve tam olarak bunu yapmak için nasıl https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html okuyun.

Bazı kod

olacak sizin:

#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

Stellar. Daha yakın metal çalışma zamanı çılgınlığı için mükemmel kaynak. –

+0

Çok teşekkürler, iyi çalışıyor, çalışma zamanında bir nesne özelliklerini diğerine nasıl kopyalarım? –

+1

@PavanSaberjack 'valueForKey:' ve 'setValue: forKey:' kullanarak, char karakterinin bir tür dönüşüm olmadan nesne (yani NSString' olarak) olarak kullanılamayacağını fark etmeniz gerekir. – mvds

İlgili konular