ios – 当removeObserver为Integer属性时崩溃?

ios – 当removeObserver为Integer属性时崩溃?,第1张

概述我创建一个CustomView:UIView与XIB,加载和addObserver为NSInteger属性,如下所示: //CustomView.h @interface CustomView : UIView @property (nonatomic) NSInteger inputStateControl;@end //CustomView.m static void *kInput 我创建一个CustomVIEw:UIVIEw与XIB,加载和addobserver为NSInteger属性,如下所示:

//CustomVIEw.h

@H_502_13@@interface CustomVIEw : UIVIEw @property (nonatomic) NSInteger inputStateControl;@end

//CustomVIEw.m

@H_502_13@static voID *kinputStateControlObservingContext = &kinputStateControlObservingContext;@implementation CustomVIEw- (ID)init{ self = [super init]; if (self) { // Initialization code NSArray *nib = [[NSBundle mainBundle] loadNibnamed:@"CustomVIEw" owner:self options:nil]; self = [nib objectAtIndex:0]; // [self commonInit]; } return self;}-(voID)commonInit{[self addobserver:self forKeyPath:@"inputStateControl" options:NSkeyvalueObservingOptionold context:kinputStateControlObservingContext];}#pragma mark Observer- (voID)observeValueForKeyPath:(Nsstring *)keyPath ofObject:(ID)object change:(NSDictionary *)change context:(voID *)context { if ( context == kinputStateControlObservingContext ) { NSInteger oldState = [[change objectForKey:NSkeyvalueChangeoldKey] integerValue]; if ( oldState != self.inputStateControl ) { NSLog(@"CONTEXT change %i to %i",oldState,self.inputStateControl); } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; }}-(voID)dealloc{ [self removeObserver:self forKeyPath:@"inputStateControl"];// [self removeObserver:self forKeyPath:@"inputStateControl" context:kinputStateControlObservingContext];}@end

如果我在dealloc中注释掉removeObserver,那么一切正常,这里是日志:

@H_502_13@CONTEXT change 0 to 2

但是当removeObserver,App崩溃时:

@H_502_13@*** Terminating app due to uncaught exception 'NSRangeException',reason: 'Cannot remove an observer <Keyboard 0x6a8bcc0> for the key path "inputStateControl" from <Keyboard 0x6a8bcc0> because it is not registered as an observer.'

注释加载CustomVIEw.xib时没有崩溃,但没有XIB没有任何关系.
我的代码有什么问题?

如何使用Custom Xib在CustomVIEw中为NSInteger属性添加和删除Observer?

提前致谢!

*编辑:我添加我的代码,以使我的问题清楚.请帮忙!

https://github.com/lequysang/github_zip/blob/master/CustomViewKVO.zip

解决方法 这是正在发生的事情 – 在vIEwDIDLoad方法中,您调用[[CustomVIEw alloc] init].这将创建一个新的CustomVIEw实例,并在其上调用init.但是,在init中,您从nib加载一个新实例,并将self替换为nib中的一个实例.这会导致您从alloc创建的实例并使用self = [super init]进行设置;要解除分配,因为没有更强烈的引用.由于此实例在调用commonInit之前被释放,因此它从不会观察自己的属性,因此将自身移除为观察者会导致异常.

解决这个问题的一种方法是直接从视图控制器中的nib加载视图,或者在CustomVIEw上创建一个类方法

@H_502_13@NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibnamed:@"CustomVIEw" owner:nil options:nil];CustomVIEw *customVIEw = topLevelObjects[0];

如果您采用这种方法,请丢弃init实现并将其替换为initWithCoder:这样做:

@H_502_13@- (ID)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; if (self) { _inputStateControl = 0; [self commonInit]; } return self;}

实现initWithCoder的原因是:从nib加载视图时会自动调用它.您只需要实现它,您就可以进行已在init中进行的设置.还要确保你的dealloc是这样实现的:

@H_502_13@-(voID)dealloc{ [self removeObserver:self forKeyPath:@"inputStateControl" context:kinputStateControlObservingContext];} 总结

以上是内存溢出为你收集整理的ios – 当removeObserver为Integer属性时崩溃?全部内容,希望文章能够帮你解决ios – 当removeObserver为Integer属性时崩溃?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1052621.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存