使用object_setIvar时的EXC_BAD_ACCESS

时间:2014-03-10 17:13:53

标签: ios objective-c objective-c-runtime

我正在尝试在我使用下面的代码分配的运行时类上添加和设置Ivars。我对Objective-c运行时函数没有任何经验,这就是我试图学习的原因。

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

每次运行上面的代码时,我都会在行object_setIvar(objectClass, ivar, [value copy]);上收到EXC_BAD_ACCESS(代码= 2,地址= 0x10)错误。我不明白为什么我会收到这个错误。我在尝试设置Ivar值之前检查Ivar是否成功添加到类中,但显然ivar是零。我试过NSLog的ivar,但是我得到了同样的错误。

我尝试在Google上搜索解决方案,但我找不到有关objective-c运行时函数的更多信息。

我正在使用ARC并在iOS模拟器上运行该应用程序。

1 个答案:

答案 0 :(得分:2)

您无法在上设置实例变量的值。 创建并注册该类后,您可以创建该类的实例

id myInstance = [[objectClass alloc] init];

然后在此对象上设置实例变量的值:

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