任何与objc_setAssociatedObject和objc_getAssociatedObject的陷阱?

Zev*_*erg 6 objective-c objective-c-runtime ios

我正在研究如何将属性(在这种情况下为整数)添加到所有UIView实例,无论它们是否是子类.是否使用objc_setAssociatedObject()objc_getAssociatedObject()在一个类别中以适当的Apple认可方式执行此操作?

我听说过一些关注,这构成了"运行时黑客",并且可能导致难以追踪和调试的问题.有没有人见过这类问题?有没有更好的方法在UIView没有子类化的情况下向所有实例添加整数属性?

更新:我不能只使用tag,因为这需要在已经tag用于其他事情的代码库中使用.相信我,如果我能用tag它,我会的!

Gab*_*lla 8

只要你想在一个类上伪造一个ivar,相关的对象就派上用场了.它们非常通用,因为您可以将任何对象与该类相关联.

也就是说,你应该明智地使用它,只适用于子类化感觉很麻烦的小事情.

但是,如果您的唯一要求是向所有UIView实例添加一个整数,那么tag就是要走的路.它已经存在并准备好供您使用,因此不需要涉及运行时修补UIView.

如果你想要UIView用超过整数的东西来标记你的东西,比如通用对象,你可以定义一个如下的类别.

UIView的+ Tagging.h

@interface UIView (Tagging)
@property (nonatomic, strong) id customTag;
@end
Run Code Online (Sandbox Code Playgroud)

UIView的+ Tagging.m

#import <objc/runtime.h>

@implementation UIView (Tagging)
@dynamic customTag;

- (id)customTag {
    return objc_getAssociatedObject(self, @selector(customTag));
}

- (void)setCustomTag:(id)aCustomTag {
    objc_setAssociatedObject(self, @selector(customTag), aCustomTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end
Run Code Online (Sandbox Code Playgroud)

The trick of using a property's selector as key, has recently been proposed by Erica Sadun in this blog post.

  • 然而,这种模式存在巨大的缺点,因为它导致*意大利面条代码*,其中您的类和功能与系统类/功能交错,以便将来的重构变得困难(以及维护).这个*特定*示例相对无害,但前缀属性与您的应用程序独特的东西! (4认同)