我在现有类上有一个类别,它为类添加了一个属性和一些方法。
@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
答案 0 :(得分:12)
嗯,这有点问题,因为你的代码错了。
@interface AClass () {//...
)中声明新的实例变量,但这与类别(@interface AClass (ACategory)
)不同。@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。
答案 1 :(得分: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文档为here。
我花了一段时间才找到,所以我希望它可以帮助别人。