Question

It seems that our apps which use getPropertyType(..) are failing under ios7. For whatever reason, getPropertyType(..) on for example a NSString property returns NSString$'\x19\x03\x86\x13 as the type, instead of just NSString, and also instead of NSNumber it returns NSNumber\xf0\x90\xae\x04\xff\xff\xff\xff. All of this is causing some tricky problems when i later on check against a specific type. I have changed this (legacy?) code to use isKindOfClass instead, but it bothers me that I don't understand whats going on here.

The code in question:

#import <objc/runtime.h>

static const char *getPropertyType(objc_property_t property) {
    const char *attributes = property_getAttributes(property);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T') {
            return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
        }
    }
    return "@";
}

What on earth is going on, why are the results different??

Was it helpful?

Solution

The buffer returned by getPropertyType isn't NULL terminated. I think it's only dumb luck that it ever worked. Also, returning the data pointed to by a newly created NSData is not guaranteed to work once that function returns.

I'd make this return an NSString.

NSString* getPropertyType(objc_property_t property) {
    const char *attributes = property_getAttributes(property);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T') {
            return [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
        }
    }
    return @"@";
}

This assumes ARC.

OTHER TIPS

The return value of your method need not be NULL-terminated, as it points to the internal memory of an NSData object. This would explain random bytes after your expected output.

Note also that the return value might not point to valid memory at all if the NSData object is destroyed (which might be at any time after your function returns).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top