最近,我需要这样做(将状态添加到类别)。 @Dave DeLong 对此有正确的看法。在研究最佳方法时,我发现了 Tom Harrington 的出色 blog post。我喜欢@JeremyP 在类别上使用@property 声明的想法,但不喜欢他的特定实现(不喜欢全局单例或持有全局引用)。关联引用是必经之路。
这里是添加(看起来是)ivars 到您的类别的代码。我已经在博客上详细介绍了这一点here。
在 File.h 中,调用者只能看到干净的高级抽象:
@interface UIViewController (MyCategory)
@property (retain,nonatomic) NSUInteger someObject;
@end
在 File.m 中,我们可以实现@property(注意:这些不能是@synthesize'd):
@implementation UIViewController (MyCategory)
- (NSUInteger)someObject
{
return [MyCategoryIVars fetch:self].someObject;
}
- (void)setSomeObject:(NSUInteger)obj
{
[MyCategoryIVars fetch:self].someObject = obj;
}
我们还需要声明和定义 MyCategoryIVars 类。为了便于理解,我已经按照正确的编译顺序对此进行了解释。 @interface 需要放在 Category @implementation 之前。
@interface MyCategoryIVars : NSObject
@property (retain,nonatomic) NSUInteger someObject;
+ (MyCategoryIVars*)fetch:(id)targetInstance;
@end
@implementation MyCategoryIVars
@synthesize someObject;
+ (MyCategoryIVars*)fetch:(id)targetInstance
{
static void *compactFetchIVarKey = &compactFetchIVarKey;
MyCategoryIVars *ivars = objc_getAssociatedObject(targetInstance, &compactFetchIVarKey);
if (ivars == nil) {
ivars = [[MyCategoryIVars alloc] init];
objc_setAssociatedObject(targetInstance, &compactFetchIVarKey, ivars, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[ivars release];
}
return ivars;
}
- (id)init
{
self = [super init];
return self;
}
- (void)dealloc
{
self.someObject = nil;
[super dealloc];
}
@end
上面的代码声明并实现了保存我们的 ivars (someObject) 的类。由于我们无法真正扩展 UIViewController,因此必须这样做。