如果它是iOS 7并且我包含spcluster自定义地图(超级引脚映射),我只会收到此错误。为什么会出现此错误以及如何解决?
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <MKMapAnnotationManager 0xb355a00> for the key path "coordinate" from <Annotation 0x194c1470> because it is not registered as an observer.'
答案 0 :(得分:4)
我有同样的问题。
你可以通过这样做来解决它。
var observers: NSMutableSet! = NSMutableSet()
override func addObserver(observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions, context: UnsafeMutablePointer) {
let observerId : String = "\(observer.hashValue)\(keyPath)"
self.observers.addObject(observerId)
super.addObserver(observer, forKeyPath: keyPath, options: options, context: context)
}
override func removeObserver(observer: NSObject, forKeyPath keyPath: String) {
let observerId : String = "\(observer.hashValue)\(keyPath)"
if (self.observers.containsObject(observerId)) {
self.observers.removeObject(observerId)
super.removeObserver(observer, forKeyPath: keyPath)
}
}
对于调试,如果在removeObserver()中的 else 块内添加“NSLog”语句,您可以看到偶尔MKMapView(或它的MKAnnotationManager)将随机决定删除MKAnnotation的观察它已被要求进行观察以从中删除。根据Apple自己的KVO文档,这是不可行的。
这些覆盖“修复”问题,因为它们跟踪(在每个注释的基础上)已经为每个注释记录了哪些观察结果,因此允许您拒绝去除已观察到的东西(或者从未在第一时间观察过。)
这很糟糕,但他们修复了我的动画崩溃。并且这样做没有太多的性能开销。
答案 1 :(得分:2)
根据我的经验,其常见原因是通过多元素密钥路径观察到coordinate
,并且以非KVO兼容方式修改了其中一个中间密钥。这使得内部KVO机器在认为它正在观察不同的东西时会观察到一件事。一段时间之后,当以符合KVO的方式更改密钥路径的一部分时,会引发此异常。
答案 2 :(得分:1)
在MKMapView上只使用经典注释时,我遇到了一个更普遍的问题。
尝试执行mMapView.removeAnnotations(mMapView.annotations)
时,我随机遇到了这次崩溃。
只需将其更改为:
for annotation in mMapView.annotations {
mMapView.deselectAnnotation(annotation as! MKAnnotation, animated: false)
mMapView.removeAnnotation(annotation as! MKAnnotation)
}
解决了我的问题。
我可以将它与@Aurelien Porte的评论联系起来。
答案 3 :(得分:0)
您(或开发该组件的任何人)正在尝试通过调用MKMapAnnotationManager
删除Annotation
coordinate
(关键路径removeObserver:forKeyPath:context:
)的观察者。但是MKMapAnnotationManager
未注册为观察者,因此崩溃。
此修复是为了确保对addObserver
/ removeObserver
的呼叫始终保持平衡。
没有进一步的细节,可以这么说。
作为额外参考,以下是此nice blog article about KVO的相关引用:
或许对KVO最深刻的烦恼是,如果你在对象未注册为观察者的情况下调用 -
removeObserver:forKeyPath:context:
(无论是因为它尚未注册或首先未注册),抛出一个例外。踢球者是没有内置的方法来检查对象是否已注册!
答案 4 :(得分:0)
当使用apple文档提供的一些代码来集群化MKMapView注释时,我遇到了这样的错误。它可以在示例项目PhotoMap中找到。
我的问题是在动画完成之前已取消分配父视图和MKMapView。动画正在为注释坐标设置动画(正在移动地图上的注释)
for (MyMKAnnotation *annotation in filteredAnnotationsInBucket) {
// give all the other annotations a reference to the one which is representing them
annotation.clusterAnnotation = annotationForGrid;
annotation.containedAnnotations = nil;
// remove annotations which we've decided to cluster
if ([visibleAnnotationsInBucket containsObject:annotation]) {
CLLocationCoordinate2D actualCoordinate = annotation.coordinate;
// This is the flag that I added to disable/enable animation
if (animateMarkerClustering) {
// This animation is not finished properly before the annotationViews
// animation gets finished
[UIView animateWithDuration:0.3 animations:^{
annotation.coordinate = annotation.clusterAnnotation.coordinate;
} completion:^(BOOL finished) {
annotation.coordinate = actualCoordinate;
[_mapView removeAnnotation:annotation];
}];
} else {
annotation.coordinate = actualCoordinate;
[_mapView removeAnnotation:annotation];
}
}
}
我尝试删除[self.view removeAllAnimations]
和
if (_mapView.annotations.count > 0){
NSArray *annotations =_mapView.annotations;
for(int i=0;i<annotations.count;i++){
id <MKAnnotation> annotation = annotations[i];
[[_mapView viewForAnnotation:annotation].layer removeAllAnimations];
[_mapView removeAnnotation:annotation];
}
//[_mapView removeAnnotations:_mapView.annotations];
}
我什么都没有。
暂时我设置animateMarkerClustering=NO
来禁用注释动画,这是有效的。没错。
答案 5 :(得分:0)
好的,我还没有足够的声誉来评论这个问题,但我用上面的答案解决了我完全相同的情况:https://stackoverflow.com/a/31231307/2248650
也像slava我使用Apple的示例项目PhotoMap作为我实现的基础,但我也将它移植到Swift。我还有子类化MKAnnotation并启用其样本中的坐标动画,我必须设置动态关键字来协调:
dynamic var coordinate: CLLocationCoordinate2D
现在,就像呈现一样,当我在删除注释之前取消选择注释
for annotation in allAnnotationsMapView.annotations {
allAnnotationsMapView.deselectAnnotation(annotation, animated: false)
allAnnotationsMapView.removeAnnotation(annotation)
}
我不再遇到异常了。
答案 6 :(得分:0)
XKAnnotation的子类
更改
const isFile = input => 'File' in window && input instanceof File;
const isBlob = input => 'Blob' in window && input instanceof Blob;
const a = new File([1,2,3], "foo.txt", {type: "text/plain"});
...
console.log(isFile(a)) // true
...
到
class Fibonacci:
def __init__(self, max = 0):
self.max = max
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max: # if n is less that 0
def FIB(number):
if number == 1 or number == 2:
return 1
else:
return FIB(number - 1) + FIB(number - 2)
self.n += 1
else:
raise StopIteration