0%

不小心重写了父类的某个方法导致的崩溃

不小心重写了父类的某个方法导致的崩溃

ZAEButton类里有一个commonInit方法,该方法会注册KVO “enabled”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}

return self;
}

- (void)commonInit
{
[self addObserver:self forKeyPath:@"enabled" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}

- (void)dealloc
{
[self removeObserver:self forKeyPath:@"enabled"];
}

ZAECountDownButton类为ZAEButton的子类,如果不仔细看父类的实现的话,可能也会定义一个commonInit方法.此时就是重写了该方法,虽然这并不是你的意愿.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}

return self;
}

- (void)commonInit
{
_duration = 30;
_autoCountDown = YES;
_timerStartState = ZAECountDownButtonTimerStartStateFromBegining;
[self addTarget:self action:@selector(buttonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self addSubview:_activityView];
_activityView.center = CGPointMake(self.bounds.size.width/2.0, self.bounds.size.height/2.0);
}

崩溃就这样产生了:

当实例化一个ZAECountDownButton对象,调用到[super initWithFrame:frame]时,由于子类和父类都有一个commonInit方法,子类会覆盖父类的方法,最终调用的是子类的commonInit方法.此时,子类就不会注册kvo,而当对象销毁时,会执行到父类的dealloc方法移除KVO,于是程序会因为KVO注册—移除不匹配而导致崩溃.

这或许就是有些框架中父类的初始化方法都有”_”的缘故吧.

觉得文章有帮助可以打赏一下哦!