覆盖@property setter和无限循环

Mar*_*cin 38 overriding subclass objective-c ios

有A类:

@interface ClassA : NSObject {
}
@property (nonatomic, assign) id prop1;
@end

@implementation
@synthesize prop1;
@end
Run Code Online (Sandbox Code Playgroud)

然后我有子类

@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
Run Code Online (Sandbox Code Playgroud)

这是无限循环,因为ClassB中的setProp1从ClassB中调用[ClassB setProp1:val].

我已经尝试过调用[super setProp1]但是这个

如何覆盖@property并在覆盖的setter中分配值?我们假设我无法修改ClassA.

She*_*ley 56

只需直接分配给实例变量,而不使用点语法来调用setter:

- (void) setProp1:(id)aProp
{
    self->prop1 = aProp;
}
Run Code Online (Sandbox Code Playgroud)

尽管如此,这种问题仍然存在.所有这些访问器确实是父母所做的 - 所以什么是重写父母的意义呢?

  • 示例仅用于示例目的. (3认同)
  • 没错,但AFAIK没有任何伤害,它可以提醒我,我正在做一些与众不同的事情,无需通过其存取方法即可访问ivar. (3认同)
  • 除非使用GCC 4.2,否则不需要`self->`部分. (2认同)

bol*_*hav 23

使用XCode 4.5+和LLVM 4.1不需要@synthesize,您将获得一个_prop1来引用.

- (void) setProp1:(id)aProp
{
    _prop1 = aProp;
}
Run Code Online (Sandbox Code Playgroud)

会工作得很好.


Chr*_*ahl 9

你不应该在setter中使用"self",因为它会创建递归调用.

此外,您应该检查以确保您没有分配相同的对象,保留新对象并在分配之前释放旧对象.

你应该重新定义setter名称,如上所述:

@synthesize prop1 = prop1_; 

...

- (void) setProp1:(id)aProp
{
    if (prop1_ != aProp) {
        [aProp retain]; 
        [prop1_ release]; 
        prop1_ = aProp;
    }
}
Run Code Online (Sandbox Code Playgroud)


pix*_*eak 5

另一种方法是将合成变量设置为另一个名称,如下所示:

@synthesize selectedQuestion = _selectedQuestion;
Run Code Online (Sandbox Code Playgroud)

然后将其称为_selectedQuestion.当你的意思是self.selectedQuestion时,这可以防止意外写入selectedQuestion.

但是,Apple建议不要使用下划线.你可以使用另一个名字,但@ Sherm的方法是最好的,imho.