2012-02-13 42 views
9

Tôi muốn tạo một lớp cơ sở Objective-C thực hiện một phép toán trên tất cả các thuộc tính (trong các kiểu khác nhau) khi chạy. Vì tên và loại tài sản sẽ không phải lúc nào cũng được biết, làm cách nào tôi có thể làm điều gì đó như thế này?Lặp qua tất cả các thuộc tính đối tượng tại thời gian chạy

@implementation SomeBaseClass 

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

EDIT: này sẽ đặc biệt hữu ích trong một tùy chỉnh - (NSString *)description: ghi đè.

Trả lời

21

Để mở rộng về câu trả lời mvds' (bắt đầu viết những dòng này trước khi tôi thấy mình), đây là một chương trình mẫu nhỏ mà sử dụng API runtime Objective-C để lặp qua và thông tin in về mỗi tài sản trong một lớp học:

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

Output: thuộc tính

tuổi tài sản: T^q, Vage
tài sản lastName thuộc tính: T @ "NSString", &, N, VlastName
tài sản firstName thuộc tính: T @ "NSString", &, N, VfirstName

Lưu ý rằng chương trình này cần phải được biên soạn với ARC đã bật.

+0

Một câu hỏi theo dõi tốt sẽ là cách trả về các giá trị của mỗi động ... Tôi đang nghĩ tự động tạo một trình truy cập, nhưng cú pháp, tôi vẫn đang cố gắng tìm ra điều đó. –

+1

Có một vài cách bạn có thể làm điều đó, nhưng đơn giản nhất là sử dụng KVC: 'id value = [self valueForKey: @" propertyName "]'. Có một chút phức tạp hơn, nơi bạn có cả hai nguyên thủy (int, float, vv) và đối tượng (NSString, vv) trở về các loại, nhưng tiền đề cơ bản sẽ làm việc. –

+0

mã này bị rò rỉ như địa ngục – mvds

14

Sử dụng

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

và đọc https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html về cách để làm điều này một cách chính xác.

Một số mã để giúp bạn đi:

#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

Sao. Tài nguyên hoàn hảo cho sự điên rồ thời gian chạy gần với kim loại. –

+0

Cảm ơn rất nhiều, hoạt động tốt, làm thế nào để tôi sao chép một thuộc tính đối tượng khác trong thời gian chạy? –

+1

@PavanSaberjack sử dụng 'valueForKey:' và 'setValue: forKey:', nơi bạn phải chú ý rằng 'char * name' không thể được sử dụng làm đối tượng (tức là' NSString') mà không có một dạng chuyển đổi nào đó. – mvds

Các vấn đề liên quan