代码之家  ›  专栏  ›  技术社区  ›  Corey Floyd

objc_setassociatedobject在iPhone模拟器中不可用

  •  8
  • Corey Floyd  · 技术社区  · 16 年前

    在3.1sdk中,Apple增加了对关联对象的支持。

    但是,模拟器不会编译包含对objc_setassociatedobject、objc_getassociatedobject等的引用的代码。(未声明的错误)

    这附近有吗?我可以让iPhone模拟器编译这段代码吗?我不想在设备上做所有的测试。


    更新

    缺陷归宿: RDAR:/ / 7477326

    2 回复  |  直到 16 年前
        1
  •  1
  •   hatfinch    16 年前

    快速而肮脏的工作区(大部分未经测试,可能是小车):

    #if TARGET_IPHONE_SIMULATOR
    
    #import <objc/runtime.h>
    
    enum {
        OBJC_ASSOCIATION_ASSIGN = 0,
        OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
        OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
        OBJC_ASSOCIATION_RETAIN = 01401,
        OBJC_ASSOCIATION_COPY = 01403
    };
    typedef uintptr_t objc_AssociationPolicy;
    
    @implementation NSObject (OTAssociatedObjectsSimulator)
    
    static CFMutableDictionaryRef theDictionaries = nil;
    
    static void Swizzle(Class c, SEL orig, SEL new) // swizzling by Mike Ash
    {
        Method origMethod = class_getInstanceMethod(c, orig);
        Method newMethod = class_getInstanceMethod(c, new);
        if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
            class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        else
            method_exchangeImplementations(origMethod, newMethod);
    }
    
    - (NSMutableDictionary *)otAssociatedObjectsDictionary
    {
        if (!theDictionaries)
        {
            theDictionaries = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
            Swizzle([NSObject class], @selector(dealloc), @selector(otAssociatedObjectSimulatorDealloc));
        }
    
        NSMutableDictionary *dictionary = (id)CFDictionaryGetValue(theDictionaries, self);
        if (!dictionary)
        {
            dictionary = [NSMutableDictionary dictionary];
            CFDictionaryAddValue(theDictionaries, self, dictionary);
        }
    
        return dictionary;
    }
    
    - (void)otAssociatedObjectSimulatorDealloc
    {
        CFDictionaryRemoveValue(theDictionaries, self);
        [self otAssociatedObjectSimulatorDealloc];
    }
    
    @end
    
    void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)
    {
        NSCAssert(policy == OBJC_ASSOCIATION_RETAIN_NONATOMIC, @"Only OBJC_ASSOCIATION_RETAIN_NONATOMIC supported");
    
        [[object otAssociatedObjectsDictionary] setObject:value forKey:[NSValue valueWithPointer:key]];
    }
    
    id objc_getAssociatedObject(id object, void *key)
    {
        return [[object otAssociatedObjectsDictionary] objectForKey:[NSValue valueWithPointer:key]];
    }
    
    void objc_removeAssociatedObjects(id object)
    {
        [[object otAssociatedObjectsDictionary] removeAllObjects];
    }
    
    #endif
    
        2
  •  3
  •   wbyoung    16 年前

    我不认为这会在3.x sdks中得到修复,所以另一个修复方法是只定义函数并通过动态查找调用下一个定义。

    页眉:

    #if TARGET_IPHONE_SIMULATOR
    enum {
        OBJC_ASSOCIATION_ASSIGN = 0,
        OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
        OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
        OBJC_ASSOCIATION_RETAIN = 01401,
        OBJC_ASSOCIATION_COPY = 01403
    };
    typedef uintptr_t objc_AssociationPolicy;
    
    void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy);
    id objc_getAssociatedObject(id object, void *key);
    void objc_removeAssociatedObjects(id object);
    #endif
    

    实施:

    #if TARGET_IPHONE_SIMULATOR
    void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy) {
        ((void (*)(id, void *, id, objc_AssociationPolicy))
         dlsym(RTLD_NEXT, "objc_setAssociatedObject")) (object, key, value, policy);
    }
    id objc_getAssociatedObject(id object, void *key) {
        return ((id (*)(id, void *))
                dlsym(RTLD_NEXT, "objc_getAssociatedObject"))(object, key);
    }
    void objc_removeAssociatedObjects(id object) {
        ((void (*)(id))
         dlsym(RTLD_NEXT, "objc_removeAssociatedObjects"))(object);
    }
    #endif
    
    推荐文章