Question

I am attempting to add and set Ivars on a runtime class that I've allocated using the code below. I do not have any experience with the objective-c runtime functions that's why I am trying to learn.

    if ([object isKindOfClass:[NSDictionary class]])
    {
        const char *className = [aName cStringUsingEncoding:NSASCIIStringEncoding];

        // Allocate the class using the class name, NSObject metaclass, and a size of 0
        Class objectClass = objc_allocateClassPair([NSObject class], className, 0);

        // Get all of the keys in the dictionary to use as Ivars
        NSDictionary *dictionaryObject = (NSDictionary *)object;
        NSArray *dictionaryObjectKeys = [dictionaryObject allKeys];

        for (NSString *key in dictionaryObjectKeys)
        {
            // Convert the NSString to a C string
            const char *iVarName = [key cStringUsingEncoding:NSASCIIStringEncoding];

            // Add the Ivar to the class created above using the key as the name
            if (class_addIvar(objectClass, iVarName, sizeof(NSString*), log2(sizeof(NSString*)), @encode(NSString*)))
            {
                // Get the newly create Ivar from the class created above using the key as the name
                Ivar ivar = class_getInstanceVariable(objectClass, iVarName);

                // Set the newly created Ivar to the value of the key
                id value = dictionaryObject[key];
                object_setIvar(objectClass, ivar, [value copy]);
            }
        }

        objc_registerClassPair(objectClass);
    }

Every time I run the above code I get a EXC_BAD_ACCESS (code=2, address = 0x10) error on the line object_setIvar(objectClass, ivar, [value copy]);. I don't understand why I am getting this error. I check if the Ivar was successfully added to the class before I attempt to set the Ivar's value, but apparently the ivar is nil. I've tried to NSLog the ivar, but I get the same error.

I tried searching on Google for a solution, but I can't find much information on the objective-c runtime functions.

I am using ARC and running the app on the iOS Simulator.

Was it helpful?

Solution

You cannot set values for the instance variables on the class. After creating and registering the class you can create an instance of the class:

id myInstance = [[objectClass alloc] init];

and then set values for the instance variables on this object:

for (NSString *key in dictionaryObjectKeys)
{
    const char *iVarName = [key cStringUsingEncoding:NSASCIIStringEncoding];

    id value = dictionaryObject[key];
    Ivar ivar = class_getInstanceVariable(objectClass, iVarName);

    object_setIvar(myInstance, ivar, [value copy]);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top