Leisure-Exploration of C Language Pointer and Array

Posted by [ArcanE] on Mon, 08 Jul 2019 02:10:07 +0200

The objc_property_t * class_copy PropertyList (Class cls, unsigned int * outCount) function is a function in runtime that copies a list of attributes of a class object and returns an array of values of type objc_property_t*. You can then traverse the array to extract each attribute value. Almost every dictionary-to-model framework needs this function.

- (NSDictionary *)properties_aps {   
    NSMutableDictionary *props = [NSMutableDictionary dictionary];   
    unsigned int outCount, i;   
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);   
    for (i = 0; i < outCount; i++) {   
        objc_property_t property = properties[i];   
        NSString *propertyName = [[[NSString alloc] initWithCString:property_getName(property)] autorelease];   
        id propertyValue = [self valueForKey:(NSString *)propertyName];   
        if (propertyValue) [props setObject:propertyValue forKey:propertyName];   
    }   
    free(properties);   
    return props;   
} 

This code contains functions to take attributes:

objc_property_t *properties = class_copyPropertyList([self class], &outCount); 
for (i = 0; i < outCount; i++) {   
    objc_property_t property = properties[i];     
} 

An array of properties of type objc_property_t* is obtained by taking out the subscript and obtaining an array element of type objc_property_t.

This expression suddenly feels a little puzzled, because if we replace objc_property_t with int:

int main(int argc, const char * argv[]) {
    int *arr = {1,2,3};
    arr[1] = 10;
    int a = arr[1];
    NSLog(@"%d", a);
    return 0;
}

In C, the essence of arrays is po int er plus offset, so when we assign arr[1], it is equivalent to 8 bit offset to arr. However, we do not open up memory space for the following address, which naturally causes EXC_BAD_ACCESS error.

So how to write a foo array variable of type * type in runtime and get an array element of type with foo[1]?

So we have to analyse how the above int is written incorrectly. Because when initializing int *arr, there is no sizeof(int)*count memory space.

The reason why it can be written as int arr[3] is that the essence of C language array is pointer plus offset. An int pointer is initialized, and a 3*sizeof(int) memory space is given, returning a pointer arr. So we can do this step manually:

typedef int integer;
typedef integer * integer_pointer;

integer_pointer * addIntegerToArr(integer_pointer p, ...) {
    integer_pointer *result = nil;
    if (p) {
        va_list args;
        int count = 1;
        integer_pointer current;
        va_start(args, p);
        while ((current = va_arg(args, integer_pointer))) {
            ++count;
        }
        va_end(args);
        
        result = (integer_pointer *)malloc((count) * sizeof(integer_pointer));
        result[0] = p;
        va_start(args, p);
        current = va_arg(args, integer_pointer);
        for (int i = 1; i < count; i++) {
            result[i] = current;
        }
        va_end(args);
    }
    return (integer_pointer *)result;
}

int main(int argc, const char * argv[]) {
    integer a = 10;
    integer b = 11;
    integer_pointer pa = &a;
    integer_pointer pb = &b;
    
    integer_pointer *r = addIntegerToArr(pa, pb);
    integer_pointer num = r[1];
    
    NSLog(@"%d", *num);
    return 0;
}

The key code is result = integer_pointer*) malloc ((count)* sizeof (integer_pointer);, so we open up a memory space and get an integer_pointer* type pointer, so we can manipulate the integer_pointer in this space by offsetting the pointer. Variables.

The reason why result looks like an array can be written as result[i] is because of the above reasons.

So remember that arrays in C are essentially pointer plus offset.

Although we are iOS developers, after all, C language can not be put aside, idle can imitate many C language features in runtime to achieve some language level learning. Although the above-mentioned content is too naive for a master who is really proficient in C/C++, the process of thinking is still very interesting. In addition, in the above exercise, I also learned the content of variable parameters.

It's not too technical, so it's just idle.

Welcome to my blog for more information http://suntao.me

Topics: iOS C Attribute