6

我在现有类上有一个类别,它向该类添加了一个属性和一些方法。

@interface AClass (ACategory) {
    NSString *aProperty;
}

@property (nonatomic, retain) NSString *aProperty;

@end

在实现文件中,我想在对象被释放时释放这个属性。但是,如果我dealloc在这个类中声明,它将根据我的理解覆盖原始类中的 dealloc。那么aProperty当对象被释放时释放它的正确方法是什么?

@implementation AClass (ACategory)

@synthesize aProperty;

- (void)dealloc {
    [aProperty release];
    // this will skip the original dealloc method from what I understand
    [super dealloc];
}

@end
4

2 回答 2

12

好吧,这有点问题,因为您的代码是错误的。

  1. 您不能在类别中声明实例变量;使用最新的 Objective-C ABI,您可以在类扩展 ( @interface AClass () {//...) 中声明新的实例变量,但这与类别 ( @interface AClass (ACategory)) 不同。
  2. 即使可以,实例变量声明的语法也是@interface在行后用大括号括起来。

您可以在类别中声明一个属性,但您必须在不使用新实例变量的情况下定义其存储(因此,@dynamic而不是@synthesize)。


至于您的实际问题,您不能调用重写方法的原始实现,除非您使用方法调配(由运行时函数如 促进method_exchangeImplementations)。无论如何,我建议不要这样做;这真的很可怕也很危险。


更新:类扩展中实例变量的解释

类扩展类似于类别,但它是匿名的,并且必须放在.m与原始类关联的文件中。看起来像:

@interface SomeClass () {
    // any extra instance variables you wish to add
}
@property (nonatomic, copy) NSString *aProperty;
@end

它的实现必须在你的类的主@implementation块中。因此:

@implementation SomeClass
// synthesize any properties from the original interface
@synthesize aProperty;
// this will synthesize an instance variable and accessors for aProperty,
// which was declared in the class extension.
- (void)dealloc {
    [aProperty release];
    // perform other memory management
    [super dealloc];
}
@end

因此,类扩展对于将私有实例变量和方法排除在公共接口之外很有用,但不会帮助您将实例变量添加到您无法控制的类中。覆盖没有问题-dealloc,因为您只需像往常一样实现它,同时为您在类扩展中引入的实例变量包括任何必要的内存管理。

请注意,这些东西只适用于最新的 64 位 Objective-C ABI。

于 2010-12-06T20:11:25.833 回答
5

顺便说一句,您可以使用关联引用来“模拟将对象实例变量添加到现有类”。

本质上,您可以添加一个关联对象,如下所示:

static void* ASI_HTTP_REQUEST;  // declare inside the category @implementation but outside any method    

// And within a method, init perhaps
objc_setAssociatedObject(self, 
    &ASI_HTTP_REQUEST, 
    request, 
    OBJC_ASSOCIATION_RETAIN);

并通过发送“nil”释放关联对象:

// And release the associated object
objc_setAssociatedObject(self,
    &ASI_HTTP_REQUEST, 
    nil, 
    OBJC_ASSOCIATION_RETAIN);

Apple 文档在这里

我花了一段时间才找到,所以我希望它可以帮助某人。

于 2011-04-14T20:52:27.337 回答