在项目开发中定义了一个单例对象RHUserData的对象,RHOLUserInfo类是单例对象的一个property属性,RHOLUserInfo里面有个userId的属性,在其他类里面进行设置KVO,
在A类里面设置监听:
[[RHOLUserData shareInstance].userInfo addObserver:self forKeyPath:@"userId" options:NSKeyValueObservingOptionNew context:nil];
在B类里面进行对RHOLUserInfo赋值操作:
[RHOLUserData shareInstance].userInfo = newUserInfo;
这个操作在iOS 11以上是不会有异常的,但是在iOS 11一下的版本就会报错,导致crash的问题:
异常日志输出:
[17369:6096714] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'An instance 0x1700cfb20 of class RHOLUserInfo was deallocated while key value observers were still registered with it.
Current observation info: <NSKeyValueObservationInfo 0x17003db80> ( <NSKeyValueObservance 0x17024ad10: Observer: 0x17404fdb0, Key path: userId, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x17024ad40> )' *** First throw call stack: (0x18b8ba1c0 0x18a2f455c 0x18b8ba108 0x18c30ad64 0x1043ec5b8 0x1000d3384 0x104386da4 0x1043861a0 0x10379ec9c 0x1037c0ff4 0x1055f125c
0x1055f121c 0x1055f5fb0 0x18b867f2c 0x18b865b18 0x18b794048 0x18d21a198 0x1917802fc 0x19177b034 0x1001270c0 0x18a7785b8) libc++abi.dylib: terminating with uncaught exception of type NSException
在错误日志里面也提醒的很清楚,“RHOLUserInfo was deallocated while key value observers were still registered with it”,意思是说单例里面的RHOLUserInfo属性旧内存已经被释放了但是KVO还是继续监听,
解决方案:
最简单的解决方案是RHOLUserInfo里面的property属性相对就少的情况下(3个以下),可以进行手动赋值:
[RHOLUserData shareInstance].userInfo.userId = newUserInfo.userId;
复杂的对象属性特别多的时候,这样写就太糟糕了,推荐使用YYKit里面的YYModel进行属性赋值操作安全方便:)
[[RHOLUserData shareInstance].userInfo modelSetWithDictionary:[newuserInfo toDictionary]];
注意:以上对象都是继承了JSONModel对象才能进行对象转换字典的操作。