Исключение при масштабировании с наложениями на MKMapView: NSInvalidArgumentException NSSetM removeObject: объект не может быть нулевым

Я добавляю около 1000 MKPolygons к MKMapView. После добавления наложений на MKMapView все работает нормально. Однако, если я быстро увеличиваю и уменьшаю масштаб (иногда отпуская масштаб, чтобы mapView обрабатывал его новым visibleMapRect), я обнаружил, что приложение (иногда) аварийно завершает работу со следующей трассировкой стека исключений:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSSetM removeObject:]: object cannot be nil'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000107db6b0b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010781b141 objc_exception_throw + 48
    2   CoreFoundation                      0x0000000107d1712a -[__NSSetM removeObject:] + 538
    3   VectorKit                           0x000000010bae84fa -[VKRasterOverlayTileSource removeOverlay:] + 89
    4   VectorKit                           0x000000010b79a648 -[VKMapModel removeRasterOverlay:] + 68
    5   MapKit                              0x0000000106f93bf1 -[MKOverlayContainerView _removeDrawable:forOverlay:level:] + 502
    6   MapKit                              0x0000000106f92633 -[MKOverlayContainerView addAndRemoveOverlayViews] + 785
    7   MapKit                              0x0000000106f44772 -[MKMapView _didChangeRegionMidstream:] + 229
    8   MapKit                              0x0000000106f49528 -[MKMapView mapLayer:didChangeRegionAnimated:] + 91
    9   VectorKit                           0x000000010b7d39e8 -[VKMapCameraController rotateToYaw:withPoint:animated:] + 884
    10  VectorKit                           0x000000010b7d4e7b -[VKMapCameraController snapMapIfNecessary:] + 389
    11  MapKit                              0x0000000106f93bf1 -[MKOverlayContainerView _removeDrawable:forOverlay:level:] + 502
    12  MapKit                              0x0000000106f92633 -[MKOverlayContainerView addAndRemoveOverlayViews] + 785
    13  MapKit                              0x0000000106f44772 -[MKMapView _didChangeRegionMidstream:] + 229
    14  MapKit                              0x0000000106f49528 -[MKMapView mapLayer:didChangeRegionAnimated:] + 91
    15  VectorKit                           0x000000010b9f7b0e -[VKScreenCameraController stopPinchingWithFocusPoint:] + 64
    16  MapKit                              0x0000000106fbb1e3 __38-[MKMapGestureController handlePinch:]_block_invoke.184 + 126
    17  VectorKit                           0x000000010b78aaa2 -[VKAnimation stopAnimation:] + 109
    18  VectorKit                           0x000000010b8f9a3d -[VKDynamicAnimation stopAnimation:] + 45
    19  MapKit                              0x0000000106fb7819 -[MKMapGestureController stopDynamicAnimations] + 50
    20  MapKit                              0x0000000106fba254 -[MKMapGestureController gestureRecognizerTouchesBegan:] + 39
    21  MapKit                              0x0000000106fbbab1 -[_MKUserInteractionGestureRecognizer touchesBegan:withEvent:] + 198
    22  UIKit                               0x0000000108e9b934 -[UIGestureRecognizer _touchesBegan:withEvent:] + 113
    23  UIKit                               0x0000000108e8901c __55-[UIGestureEnvironment _updateGesturesForEvent:window:]_block_invoke + 337
    24  UIKit                               0x0000000108e89b79 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 282
    25  UIKit                               0x0000000108e88e0a -[UIGestureEnvironment _updateGesturesForEvent:window:] + 274
    26  UIKit                               0x00000001089d4eea -[UIWindow sendEvent:] + 4092
    27  UIKit                               0x0000000108981a84 -[UIApplication sendEvent:] + 352
    28  UIKit                               0x00000001091655d4 __dispatchPreprocessedEventFromEventQueue + 2926
    29  UIKit                               0x000000010915d532 __handleEventQueue + 1122
    30  UIKit                               0x000000010915e800 __handleEventQueue + 5936
    31  CoreFoundation                      0x0000000107d5cc01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    32  CoreFoundation                      0x0000000107d420cf __CFRunLoopDoSources0 + 527
    33  CoreFoundation                      0x0000000107d415ff __CFRunLoopRun + 911
    34  CoreFoundation                      0x0000000107d41016 CFRunLoopRunSpecific + 406
    35  GraphicsServices                    0x000000010cc97a24 GSEventRunModal + 62
    36  UIKit                               0x0000000108964134 UIApplicationMain + 159
    37  MyProject                                0x0000000106e51a9f main + 111
    38  libdyld.dylib                       0x000000010e56165d start + 1

Это не всегда происходит. Часто бывает довольно редко. Вы можете видеть, что трудно отлаживать и выяснять, что происходит не так, потому что мой проект не отображается в трассировке стека (за исключением того, что он работает в моем приложении...).

Пытаясь отследить проблему, я создал очень простое приложение, в котором не было ничего, кроме MKMapView и 1000 случайных MKPolygons с 5 случайно сгенерированными CLLocationCoordinate2D в каждом. Я обнаружил, что приложение по-прежнему вылетает при масштабировании, отдыхе, масштабировании, отдыхе и т. д. Но менее вероятно? Все, что я здесь делаю, это добавляю базовые случайные MKPolygons к MKMapView! Обратите внимание, что MKPolygonRenderer для каждого MKPolygon ничего не делает, кроме случайного fillColor.

Примечание. Я запускаю приложение в Xcode на симуляторе iPhone 7.

Что здесь не так? Спасибо!


person Bechsh    schedule 17.08.2017    source источник
comment
Сообщение [__NSSetM removeObject:]: object cannot be nil довольно ясно. Найдите место, где объект удален из NSMutableSet, и добавьте проверку nil.   -  person vadian    schedule 17.08.2017
comment
reason: '*** -[__NSSetM removeObject:]: object cannot be nil' Здесь нужно удалить какой-то объект. Может быть, ваш массив Annotation дает такой пустой контент? Используйте Exception error handling, он автоматически покажет ваш класс аварии и строку.   -  person Mathi Arasan    schedule 17.08.2017
comment
Этот NSMutableSet где-то глубоко вложен в структуру MapKit, я не могу изменить этот код. Я также не использую никаких Annotations. Только MKPolygon, все из которых не-nil.   -  person Bechsh    schedule 17.08.2017
comment
Вы нашли решение? Такая же проблема сейчас :(   -  person Skyborg    schedule 13.05.2019
comment
@Skyborg, к сожалению, нет, возможно, это ошибка в структуре карт Apple, которую они когда-нибудь исправят? Это редкость, я перестал испытывать это.   -  person Bechsh    schedule 30.05.2019
comment
я перешел на мапбокс. Проблема существует более 1,5 лет, и Apple не исправила ее.   -  person Skyborg    schedule 02.06.2019


Ответы (1)


У меня была очень похожая проблема при добавлении и удалении аннотаций в виде карты.

В ответ оказалось, что все, что обращается к аннотациям, даже вычисления, которые только читают массив аннотаций, помещаются в основной поток.

Я только поместил фактическое добавление и удаление в основной поток, и по большей части это было нормально, но случайный сбой с

[__NSSetM removeObject:]: объект не может быть нулевым

person UglyBlueCat    schedule 05.07.2018
comment
Спасибо за Ваш ответ. Сначала я подумал, что это может быть проблема с потоками, но я делаю все в приведенном выше примере, который терпит неудачу, в основном потоке. - person Bechsh; 06.07.2018