3

在文档中...

objc_setAssociatedObject

使用给定键和关联策略为给定对象设置关联值。

void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)

参数object 关联的源对象。

key关联的键。

value要与对象的键 key 关联的值。通过 nil 清除现有关联。

policy关联的策略。有关可能的值,请参阅“关联对象行为”。</p>

不清楚的是,当您调用objc_setAssociatedObject()删除关联时,是否有必要使用与最初设置属性相同的策略?还是objc_setAssociatedObject()只是使用适当的策略来“撤消”前一组?我假设它必须忽略该策略,否则如果您只是设置另一个值,则之前的值也需要使用相同的策略进行设置。不同之处在于,在某些情况下,当前存储的属性的引用计数会被调整,而在其他情况下则不会。

很明显,系统确实在内部跟踪它,否则泛型objc_removeAssociatedObjects()将永远无法工作,而 ARC 无论如何都需要知道这一点才能工作。

我个人需要知道的原因是以下代码片段:

typedef const void* associatedPropertyKeyToken;

-(NSMutableDictionary*) associatedInfo{
    NSMutableDictionary *result = [self associatedPropertyForKey:NSAsssociatedInfo];
    if (!result) {

        [self retainAssociatedProperty:(result = [NSMutableDictionary dictionary])
                                forKey:NSAsssociatedInfo];
    }
    return result;
}

-(BOOL) associatedPropertyForKeyExists:(associatedPropertyKeyToken)aKey {
#if DEBUG_ASSOCIATED
    BOOL result =
#else
    return
#endif

    objc_getAssociatedObject(self,aKey)!=nil;

#if DEBUG_ASSOCIATED
    NSLog(@"getting associatedPropertyForKeyExists:%@ = %@",NSStringFromAssociatedPropertyKeyToken(aKey),
          result ? @"YES" : @"NO");
    return result;
#endif
}


-(void) assignAssociatedProperty:(id)prop forKey:(associatedPropertyKeyToken)aKey{
#if DEBUG_ASSOCIATED
    NSLog(@"assigning associatedPropertyForKey:%@ <= %@",NSStringFromAssociatedPropertyKeyToken(aKey),
          prop);
#endif
    objc_setAssociatedObject(self,aKey, prop, OBJC_ASSOCIATION_ASSIGN);
}

-(void) retainAssociatedProperty:(id)prop forKey:(associatedPropertyKeyToken)aKey{
#if DEBUG_ASSOCIATED
    NSLog(@"retaining associatedPropertyForKey:%@ <= %@",NSStringFromAssociatedPropertyKeyToken(aKey),
          prop);
#endif
    objc_setAssociatedObject(self, aKey, prop, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(void) removeAssociatedPropertyForKey:(associatedPropertyKeyToken)aKey{
#if DEBUG_ASSOCIATED
    NSLog(@"removing associatedPropertyForKey:%@",NSStringFromAssociatedPropertyKeyToken(aKey));
#endif
    objc_setAssociatedObject(self,aKey,  NULL, OBJC_ASSOCIATION_ASSIGN);
}
4

1 回答 1

4

policy参数objc_setAssociatedObject指定运行时应该如何处理value同一个函数调用的参数,而不是它应该如何处理任何其他对象(例如相同的先前或未来值key)。因此,您关联时给出value的策略就是您取消关联时使用的策略value

您可以验证实现是否以这种方式运行,因为 Objective-C 运行时的源代码是开源的。您可以在 中找到处理关联引用的代码objc-references.mm。感兴趣的函数是_object_set_associative_reference,哪些调用ReleaseValue,哪些调用releaseValue

于 2013-11-12T04:08:16.557 回答