Queste risposte sono utili, ma ne ho bisogno di più. Tutto quello che voglio fare è verificare se il tipo di classe di una proprietà è uguale a quello di un oggetto esistente. Tutti i codici di cui sopra non sono in grado di farlo, perché: Per ottenere il nome della classe di un oggetto, object_getClassName () restituisce testi come questi:
__NSArrayI (for an NSArray instance)
__NSArrayM (for an NSMutableArray instance)
__NSCFBoolean (an NSNumber object initialized by initWithBool:)
__NSCFNumber (an NSValue object initialized by [NSNumber initWithBool:])
Ma se si richiama getPropertyType (...) dal codice di esempio sopra, con 4 strutture objc_property_t di proprietà di una classe definita in questo modo:
@property (nonatomic, strong) NSArray* a0;
@property (nonatomic, strong) NSArray* a1;
@property (nonatomic, copy) NSNumber* n0;
@property (nonatomic, copy) NSValue* n1;
restituisce stringhe rispettivamente come segue:
NSArray
NSArray
NSNumber
NSValue
Quindi non è in grado di determinare se un NSObject è in grado di essere il valore di una proprietà della classe. Come farlo allora?
Ecco il mio codice di esempio completo (la funzione getPropertyType (...) è la stessa di sopra):
#import <objc/runtime.h>
@interface FOO : NSObject
@property (nonatomic, strong) NSArray* a0;
@property (nonatomic, strong) NSArray* a1;
@property (nonatomic, copy) NSNumber* n0;
@property (nonatomic, copy) NSValue* n1;
@end
@implementation FOO
@synthesize a0;
@synthesize a1;
@synthesize n0;
@synthesize n1;
@end
static const char *getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
//printf("attributes=%s\n", attributes);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T' && attribute[1] != '@') {
// it's a C primitive type:
// if you want a list of what will be returned for these primitives, search online for
// "objective-c" "Property Attribute Description Examples"
// apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
// it's an ObjC id type:
return "id";
}
else if (attribute[0] == 'T' && attribute[1] == '@') {
// it's another ObjC object type:
NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
}
return "";
}
int main(int argc, char * argv[]) {
NSArray* a0 = [[NSArray alloc] init];
NSMutableArray* a1 = [[NSMutableArray alloc] init];
NSNumber* n0 = [[NSNumber alloc] initWithBool:YES];
NSValue* n1 = [[NSNumber alloc] initWithBool:NO];
const char* type0 = object_getClassName(a0);
const char* type1 = object_getClassName(a1);
const char* type2 = object_getClassName(n0);
const char* type3 = object_getClassName(n1);
objc_property_t property0 = class_getProperty(FOO.class, "a0");
objc_property_t property1 = class_getProperty(FOO.class, "a1");
objc_property_t property2 = class_getProperty(FOO.class, "n0");
objc_property_t property3 = class_getProperty(FOO.class, "n1");
const char * memberthype0 = getPropertyType(property0);//property_getAttributes(property0);
const char * memberthype1 = getPropertyType(property1);//property_getAttributes(property1);
const char * memberthype2 = getPropertyType(property2);//property_getAttributes(property0);
const char * memberthype3 = getPropertyType(property3);//property_getAttributes(property1);
NSLog(@"%s", type0);
NSLog(@"%s", type1);
NSLog(@"%s", type2);
NSLog(@"%s", type3);
NSLog(@"%s", memberthype0);
NSLog(@"%s", memberthype1);
NSLog(@"%s", memberthype2);
NSLog(@"%s", memberthype3);
return 0;
}