objc_setAssociatedObject在iPhone模拟器中不可用 [英] objc_setAssociatedObject unavailable in iPhone simulator

查看:132
本文介绍了objc_setAssociatedObject在iPhone模拟器中不可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在3.1 SDk中,Apple添加了对关联对象的支持。



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



这附近有没有?我可以让iPhone模拟器编译这段代码吗?

>

错误提交:
rdar:// 7477326

解决方案

快速和肮脏的解决方法(大部分未测试,可能是错误的):

  #if TARGET_IPHONE_SIMULATOR 

#import < objc / runtime.h>

枚举{
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)//由Mike Ash调用sw
{
方法origMethod = class_getInstanceMethod(c,orig);
方法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
else
method_exchangeImplementations(origMethod,newMethod);
}

- (NSMutableDictionary *)otAssociatedObjectsDictionary
{
if(!theDictionaries)
{
theDictionaries = CFDictionaryCreateMutable(NULL, NULL,& kCFTypeDictionaryValueCallBacks);
Swizzle([NSObject类],@selector(dealloc),@selector(otAssociatedObjectSimulatorDealloc));
}

NSMutableDictionary * dictionary =(id)CFDictionaryGetValue(theDictionaries,self);
if(!dictionary)
{
dictionary = [NSMutableDictionary dictionary];
CFDictionaryAddValue(theDictionaries,self,dictionary);
}

返回字典;
}

- (void)otAssociatedObjectSimulatorDealloc
{
CFDictionaryRemoveValue(the Dictionary,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


In the 3.1 SDk, Apple added support for associated objects.

However, the simulator will not compile code that includes references to objc_setAssociatedObject, objc_getAssociatedObject, et al. (Undeclared errors)

Is there away around this? Can I make the iPhone simulator compile this code? I would hate to have to do all testing on the device.


Update

Bug Filed: rdar://7477326

解决方案

A quick and dirty workaround (largely untested, may be buggy):

#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

这篇关于objc_setAssociatedObject在iPhone模拟器中不可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆