2012-02-13 35 views
9

我想創建一個Objective-C基類,該類在運行時對所有屬性(不同類型)執行操作。由於這些屬性的名稱和類型不會總是被知道,我該如何做這樣的事情?在運行時環回所有對象屬性

@implementation SomeBaseClass 

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

編輯:這將是一個自定義- (NSString *)description:覆蓋特別有用。

回答

21

要在MVDS的回答擴大(開始寫這個我看到了他之前),這裏是通過使用Objective-C的運行時API循環一點點樣本程序大約在一個類中的每個屬性的打印信息:

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

輸出:

物業年齡屬性:T^q,Vage
物業的lastName屬性:T @家 「的NSString」,&,N,VlastName
物業的firstName屬性:T @家 「的NSString」,&,N,VfirstName

注意,此計劃需要與ARC編譯打開。

+0

一個好的後續問題將是如何返回每個動態值...我想動態地創建一個訪問器,但在語法上,我仍然試圖找出。 – 2012-02-14 00:07:58

+1

有幾種方法可以做到這一點,但最直接的方法是使用KVC:'id value = [self valueForKey:@「propertyName」]''。在你有原始(int,float等)和對象(NSString等)返回類型的地方獲得更復雜一點,但基本前提將起作用。 – 2012-02-14 00:37:45

+0

這段代碼像地獄一樣泄漏 – mvds 2012-02-14 00:53:01

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

恆星。完美的資源,用於接近金屬運行時的瘋狂。 – 2012-02-13 23:18:57

+0

非常感謝,效果很好,我如何在運行時將一個對象屬性複製到其他對象? – 2012-12-27 14:43:22

+1

@PavanSaberjack使用'valueForKey:'和'setValue:forKey:',你必須注意'char * name'不能用作對象(即'NSString')而沒有某種形式的轉換。 – mvds 2012-12-28 01:16:12

相關問題