覆盖@property设置器和无限循环
有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],但是这个
如何覆盖@属性和赋值覆盖setter? 假设我不能修改ClassA。
直接分配给实例variables,而不使用点语法来调用setter:
- (void) setProp1:(id)aProp { self->prop1 = aProp; }
尽pipe如此,这种问题仍然存在。 所有这个访问者所做的,正是父母所做的 – 那么重写父母有什么意义呢?
使用XCode 4.5+和LLVM 4.1不需要@synthesize,你将得到一个_prop1来引用。
- (void) setProp1:(id)aProp { _prop1 = aProp; }
将工作得很好。
你不应该在setter中使用“self”,因为这会创buildrecursion调用。
此外,你应该检查,以确保你不分配相同的对象,保留新的对象,释放旧的对象之前,分配。
你应该重新定义setter的名字,如上所示:
@synthesize prop1 = prop1_; ... - (void) setProp1:(id)aProp { if (prop1_ != aProp) { [aProp retain]; [prop1_ release]; prop1_ = aProp; } }
另一种方法是将合成variables设置为另一个名称,如下所示:
@synthesize selectedQuestion = _selectedQuestion;
然后将其称为_selectedQuestion
。 这可以防止意外self.selectedQuestion写入selectedQuestion。
不过,苹果build议不要使用下划线。 你可以使用另一个名字,但@ Sherm的方法是最好的,恕我直言。
只需在您的子类中@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