从Xcode中的“crash”部分检索的以下崩溃日志有一些问题。只有少数设备受此崩溃报告的影响。
我已经分析了这个问题,但我想这是苹果框架上的一个bug。但我找不到复制它的方法。
这里有一个类似的讨论:清除观察者:forKeyPath中的崩溃帮助:。
有什么暗示吗?
线程0名称:线程0崩溃: 0基础 0x23507591 _NSKeyValueReplaceObservationInfoForObject + 69 (NSKeyValueObserving.m:1166) 1基金会 0x23506fe7 -NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:+ 327 (NSKeyValueObserving.m:1552) 2基金会 0x23506b03 -NSObject(NSKeyValueObserverRegistration)远程观察员:forKeyPath:+ 163 (NSKeyValueObserving.m:1696) 3基金会 0x235069a7 -NSObject(NSKeyValueObserverRegistration) Remove观察者:forKeyPath:上下文:+ 219 (NSKeyValueObserving.m:1663) 4 ApplicationName 0x0002e233 -Supervisor RemoveObject观察者:forKeyPath:+ 115 (Supervisor.m:344)
removeObjectObserver:forKeyPath:在哪里
- (void) removeObjectObserver:(id)object forKeyPath:(NSString *)keyPath {
@try {
[object removeObserver:self forKeyPath:keyPath context:PrivateKVOContext];
} @catch (NSException *exception) { }
}发布于 2015-06-02 09:58:24
必须特别注意使用Observers in Objective-C:不要将相同的观察者倍数时间添加到同一个对象的属性中,如果存在这样的参数,则将删除包装起来:
if ([self observationInfo]) {
@try {
[self removeObserver:self forKeyPath:keyPath];
}
@catch (NSException *exception) {}
}您正在经历崩溃,因为您试图删除两倍的观察者,或您正在删除一个不存在的观察者。
您应该以这种方式添加observers:
[yourObject addObserver:self forKeyPath:keypath options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil/yourContext];编辑:您可以删除已经释放的对象上的观察者,从而导致此崩溃。
if (object && [self observationInfo]) {
@try {
[self removeObserver:self forKeyPath:keyPath];
}
@catch (NSException *exception) {}
}发布于 2015-06-25 07:36:26
通常,你有一个象牙塔,你可以知道你是否反对的键盘,观察在这个时候。像@property(.)BOOL textFieldTextObserving;以及添加/删除观察方法应该在添加/删除之前检查此属性,以避免添加/删除观察者两次。如果有许多观察对象和键盘(以@(BOOL)作为对象,-identifiers作为键),您也可以使用-identifiers。
无论如何,使用@try-exception做事情并不是推荐的目标-C方式。苹果公司的文档上说:
"You should not use a try-catch block in place of standard programming checks for Objective-C methods. In the case of an NSArray, for example, you should always check the array’s count to determine the number of items before trying to access an object at a given index. The objectAtIndex: method throws an exception if you make an out-of-bounds request so that you can find the bug in your code early in the development cycle—you should avoid throwing exceptions in an app that you ship to users." https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ErrorHandling/ErrorHandling.html
发布于 2019-12-21 17:13:31
现在给出答案为时已晚,但我也面临着同样的问题。所以我决定给别人写这个。
注意:崩溃的主要原因是在添加之前尝试删除一个观察者。
我已经创建了一些扩展来帮助您安全地移除观察者。斯威夫特5号
您现在可以在添加之前删除它,而不会崩溃。请确保您还删除了deinit中的观察者。
使用:
objectToObserve.safeRemoveObserver(self, keyPath: "myDate", context: &myContext)扩展:
extension NSRegularExpression {
convenience init(_ pattern: String) {
do {
try self.init(pattern: pattern)
} catch {
preconditionFailure("Illegal regular expression: \(pattern).")
}
}
func matches(_ string: String) -> Bool {
let range = NSRange(location: 0, length: string.utf16.count)
return firstMatch(in: string, options: [], range: range) != nil
}
}
extension NSObject {
func safeRemoveObserver(_ observer: NSObject, keyPath: String, context: inout Int) {
let result = checkIfAlreadyAdded(keyPath: keyPath, context: &context)
if result {
removeObserver(observer, forKeyPath: keyPath, context: &context)
}
}
fileprivate func address(_ o: UnsafeRawPointer) -> Int {
return Int(bitPattern: o)
}
fileprivate func checkIfAlreadyAdded(keyPath: String, context: inout Int) -> Bool {
guard self.observationInfo != nil else { return false }
let info = Unmanaged<AnyObject>
.fromOpaque(self.observationInfo!)
.takeUnretainedValue()
let contextStr = NSString(format: "%p", address(&context))
let infoStr = info.description ?? ""
let regex = NSRegularExpression("\(keyPath).*[a-z].*\(contextStr)")
let result = regex.matches(infoStr)
return result
}
}https://stackoverflow.com/questions/30165085
复制相似问题