【问题标题】:EXC_BAD_ACCESS when using object_setIvar使用 object_setIvar 时的 EXC_BAD_ACCESS
【发布时间】:2014-03-11 20:11:24
【问题描述】:

我正在尝试在我使用以下代码分配的运行时类上添加和设置 Ivar。我对 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 (code=2, address = 0x10) 错误。我不明白为什么我会收到这个错误。在尝试设置 Ivar 的值之前,我检查了 Ivar 是否已成功添加到类中,但显然 ivar 为 nil。我尝试 NSLog ivar,但我得到了同样的错误。

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

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

【问题讨论】:

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


    【解决方案1】:

    您不能为 上的实例变量设置值。 创建并注册类后,您可以创建该类的instance

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

    【讨论】:

    • 哦,我明白了。那讲得通。当我尝试从 iVar (object_getIvar(instance, ivar)) 中检索值时,它返回 null,但我知道我设置的值不为 null。你知道为什么会这样吗?
    • @Jonathan: id y = object_getIvar(myInstance, ivar); 在我尝试时返回之前设置的值。
    • 是否需要靠近示例末尾的[value copy]?或者只是为了复制属性?你能通过value吗?
    • @Olie:如果你不想要一个独立的实例,你可以在那里传递value。我刚刚从问题中复制了(!)那部分。
    • 在将值分配给实例变量之前,是否有一种快速添加类型检查的方法?如果类型不匹配,请不要设置它。
    猜你喜欢
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多