일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- itunes
- bash
- Detect
- backspace
- delete button
- 삭제버튼
- beanCreationException
- IPA
- KVO
- api19
- Query
- googlemap
- 색상 변경
- Cluster
- 단축키
- mysql
- 아이튠즈
- sqlSession
- dataSource
- Exception
- 삭제
- KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED
- NoClassDefFoundError
- mybatis
- Drawer
- command not found
- DELETE
- color
- 실행
- UITextField
- Today
- Total
BlueAroma
[Crash] KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED 본문
[Crash] KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED
BlueAroma 2017. 11. 9. 17:38KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED..
GMSGoogleMap 과 GMUClusterManager를 사용하는 경우 발생.
빈번하게 맵을 오가는 경우에 항상은 아니고 간헐적으로 (또는 자주) Crash 가 발생합니다.
원인은 KVO ( Key Value Observer ) 의 추가 제거가 정상적으로 이루어지지 않아 발생하는 것으로 짐작됩니다.
그렇다면 그 문제는 어디서 발생하는 것일까요?
IOS에서 구글 맵. 클러스터를 사용하는 경우 아래와 같이 클러스터 매니져를 생성해서 이용하게 됩니다.
- (void)viewDidLoad {
[super viewDidLoad]; //-- 맵 마커 클러스터링 기본 셋팅 id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init]; id<GMUClusterIconGenerator> iconGenerator = [[GMUDefaultClusterIconGenerator alloc] init]; _renderer = [[CMClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:iconGenerator];
_clusterManager = [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:_renderer]; [_clusterManager setDelegate:self mapDelegate:self]; } |
문제는 해당 MapViewController(가칭)을 빈번하게 생성하여 Push Pop을 하게되는 경우.
(예를들어 맵 -> 상세정보 -> 맵 -> 상세정보 등등..)
문제의메세지와 함께 어플이 종료됩니다.
GMUClusterManager.m 파일에서 문제의 소스를 보자면 아래와 같습니다.
static NSString *const kGMUCameraKeyPath = @"camera"; ..... - (instancetype)initWithMap:(GMSMapView *)mapView algorithm:(id<GMUClusterAlgorithm>)algorithm renderer:(id<GMUClusterRenderer>)renderer { if ((self = [super init])) { _algorithm = [[GMUSimpleClusterAlgorithm alloc] init]; _mapView = mapView; _previousCamera = _mapView.camera; _algorithm = algorithm; _renderer = renderer; // 이 Observer가 NSKeyValueObservingOptionNew(KVO) 다 [_mapView addObserver:self forKeyPath:kGMUCameraKeyPath options:NSKeyValueObservingOptionNew context:nil]; } return self; } - (void)dealloc { // KVO의 제거부분이 dealloc 함수에 들어있다. [_mapView removeObserver:self forKeyPath:kGMUCameraKeyPath];
} .......
|
여담이지만... 애플이 ARC 를 도입하면서 dealloc을 직접 호출할 일이 없어지게 되었고.
해당 dealloc 함수는 [super dealloc] 이 사라진 단순 형태만 남아있습니다.
ARC 가 처음 도입되고 나서 기존 개발자들은 (저를 포함하여..) 한동안 ARC를 사용하지 못했습니다..
이유는 정말 내가 원하는 타이밍에 메모리 해제 (dealloc)이 호출될 것인가?? 에 대한 믿음이 없었기 때문이죠.
남아있는 dealloc은 물론 언젠간 불리겠지만 원하는 타이밍에 빠릿빠릿 실행되지 않을 수 있습니다.
그렇담 이제 해결방법.
- (instancetype)initWithMap:(GMSMapView *)mapView algorithm:(id<GMUClusterAlgorithm>)algorithm renderer:(id<GMUClusterRenderer>)renderer { if ((self = [super init])) { _algorithm = [[GMUSimpleClusterAlgorithm alloc] init]; _mapView = mapView; _previousCamera = _mapView.camera; _algorithm = algorithm; _renderer = renderer; // [_mapView addObserver:self // forKeyPath:kGMUCameraKeyPath // options:NSKeyValueObservingOptionNew // context:nil]; } return self; } - (void)dealloc { // [_mapView removeObserver:self forKeyPath:kGMUCameraKeyPath];
}
|
........ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; @try { [_mapView addObserver:_clusterManager forKeyPath:@"camera" // kGMUCameraKeyPath = @"camera" options:NSKeyValueObservingOptionNew context:nil];
}@catch (NSException * e) { NSLog(@"Error: %@%@", [e name], [e reason]);
} } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated];
@try { [self.mapView removeObserver:_clusterManager forKeyPath:@"camera"]; // kGMUCameraKeyPath = @"camera" }@catch (NSException * e) { NSLog(@"Error: %@%@", [e name], [e reason]);
} }
........ |
'내맘대로 프로그래밍 > iOS' 카테고리의 다른 글
[iOS] iTunes를 이용한 iPad 설치 ( iOS11 , iTunes 12.7 이후) (1) | 2017.09.26 |
---|---|
UITextField - 키보드에서 삭제 버튼 클릭 여부 인식하기 (0) | 2017.09.07 |