A级有:
@interface ClassA : NSObject {
}
@property (nonatomic, assign) id prop1;
@end
@implementation
@synthesize prop1;
@end
然后我有子类
@interface ClassB : ClassA {
}
@end
@implementation
- (id)init {
self = [super init];
if (self) {
}
return self;
}
//This is infinite loop
- (void) setProp1:(id)aProp
{
self.prop1 = aProp;
}
@end
这是无限循环,因为ClassB中的setProp1从ClassB中调用[ClassB setProp1:val]。
我已经尝试过调用[super setProp1]但是这个
如何覆盖@property并在覆盖的setter中分配值?我们假设我无法修改ClassA。
答案 0 :(得分:56)
直接分配给实例变量,而不使用点语法来调用setter:
- (void) setProp1:(id)aProp
{
self->prop1 = aProp;
}
但是这种问题引起了人们的质疑。所有这些访问器确实是父母所做的 - 那么什么是覆盖父母的重点呢?
答案 1 :(得分:22)
使用XCode 4.5+和LLVM 4.1不需要@synthesize,您将获得一个_prop1来引用。
- (void) setProp1:(id)aProp
{
_prop1 = aProp;
}
工作得很好。
答案 2 :(得分:9)
你不应该在setter中使用“self”,因为它会创建递归调用。
此外,您应该检查以确保您没有分配相同的对象,保留新对象并在分配之前释放旧对象。
您应该重新定义设置者名称,如上所述:
@synthesize prop1 = prop1_;
...
- (void) setProp1:(id)aProp
{
if (prop1_ != aProp) {
[aProp retain];
[prop1_ release];
prop1_ = aProp;
}
}
答案 3 :(得分:5)
另一种方法是将合成变量设置为另一个名称,如下所示:
@synthesize selectedQuestion = _selectedQuestion;
然后将其称为_selectedQuestion
。当你的意思是self.selectedQuestion时,这可以防止意外写入selectedQuestion。
但是,Apple建议不要使用下划线。您可以使用其他名称,但@ Sherm的方法是最好的,imho。
答案 4 :(得分:4)
只需@synthesize
您的子类中的所需属性,然后您可以使用它作为名称直接访问该属性:
主类接口:
@interface AClass : NSObject
@property (nonatomic, assign) id<someProtocol> delegate;
@end
子类接口:
@interface BCLass : AClass
@end
子类实现:
@implementation BCLass
@synthesize delegate = _delegate;
- (void)setDelegate:(id<someProtocol>)d{
_delegate = d;
}
@end