Why removeObserver causes objc_msgSend SIGSEGV in viewWillDisappear in this code? - ios

First of all, it is a crash that I can not reproduce so I can not debug in Xcode. So I'm trying to reason it.
Stack trace:
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0xc
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x3a816b26 objc_msgSend + 5
1 Voodo 2 0x000d8933 -[TagListViewController viewWillDisappear:] (TagListViewController.m:107)
2 UIKit 0x32b68169 -[UIViewController _setViewAppearState:isAnimating:] + 472
3 UIKit 0x32bc602b -[UIViewController viewWillMoveToWindow:] + 290
4 UIKit 0x32b4be89 -[UIView _willMoveToWindow:] + 468
5 UIKit 0x32b6e4df -[UIScrollView _willMoveToWindow:] + 122
6 UIKit 0x32b4c7b5 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 77
7 UIKit 0x32b4c6e5 -[UIView _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 376
8 UIKit 0x32b4c7d5 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 109
9 UIKit 0x32b4c6e5 -[UIView _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 376
10 UIKit 0x32b4c7d5 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 109
11 UIKit 0x32b4c6e5 -[UIView _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 376
12 UIKit 0x32b4c7d5 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 109
13 UIKit 0x32b4c6e5 -[UIView _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 376
14 UIKit 0x32de333b __UIViewWillBeRemovedFromSuperview + 379
15 UIKit 0x32b4badd -[UIView removeFromSuperview] + 56
16 UIKit 0x32b4e407 -[UIView dealloc] + 366
17 UIKit 0x32d3c0f1 -[UIWindow dealloc] + 824
18 libobjc.A.dylib 0x3a818007 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 359
19 CoreFoundation 0x3030e981 _CFAutoreleasePoolPop + 16
20 UIKit 0x32b4624d _wrapRunLoopWithAutoreleasePoolHandler + 37
21 CoreFoundation 0x303a61cd __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 21
22 CoreFoundation 0x303a3b71 __CFRunLoopDoObservers + 285
23 CoreFoundation 0x303a3eb3 __CFRunLoopRun + 731
24 CoreFoundation 0x3030ec27 CFRunLoopRunSpecific + 522
25 CoreFoundation 0x3030ea0b CFRunLoopRunInMode + 106
26 GraphicsServices 0x35035283 GSEventRunModal + 138
27 UIKit 0x32bb2049 UIApplicationMain + 1136
28 Voodo 2 0x000c87df main (main.m:14)
29 libdyld.dylib 0x3ad23ab7 start + 3
The code is very simple and using ARC:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self refresh];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(refresh) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(refresh) object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
}
- (void)refresh {
[self.tableView reloadData];
// Refresh every 60s.
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(refresh) object:nil];
[self performSelector:#selector(refresh) withObject:nil afterDelay:60];
}
The crash occurs at the last line.
The only possible cause I can think of is that the cancelPreviousPerformRequestsWithTarget:selector:object: call releases the last reference to self so self is dangling at the last line. However, I can not find any possible path for this situation to happen.

Related

UITableView was deallocated while key value observers were still registered with it, Only crash in iOS9, iOS10

I remove all obsevers when dealloc, but i look crash seems like not remove success, i don't know why, everyone can help me.
this is my code and crash info. i can't figure out what's wrong with my code, anyone who can help me.
#interface SYDiagnoseFloatingView()
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, strong) NSMutableArray<UIScrollView *> *scrollViews;
#end
#implementation SYDiagnoseFloatingView
Remove obsevers
- (void)dealloc {
for (UIScrollView *scrollView in self.scrollViews) {
[scrollView removeObserver:self forKeyPath:keypath];
}
}
Add obsevers
- (void)addFloatingTargetView:(UIScrollView *)scrollView {
if ([self.scrollViews containsObject:scrollView]) {
return;
}
[self.scrollViews addObject:scrollView];
[scrollView addObserver:self forKeyPath:keypath options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
Stack trace
#0 Thread
NSInternalInconsistencyException
An instance 0x108d20600 of class UITableView was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x171428ba0> ( <NSKeyValueObservance 0x174a4b370: Observer: 0x1742f8280, Key path: contentOffset, Options: <New: YES, Old: YES, Prior: NO> Context: 0x0, Property: 0x17125db50> )
解析原始
0 CoreFoundation ___exceptionPreprocess + 124
1 libobjc.A.dylib objc_exception_throw + 56
2 CoreFoundation -[NSException initWithCoder:]
3 Foundation _NSKVODeallocate + 300
4 CoreFoundation _common_removeAllObjects + 188
5 CoreFoundation -[__NSArrayM dealloc] + 28
6 SoYoungMobile40 -[SYDiagnoseFloatingView .cxx_destruct] (SYDiagnoseFloatingView.m:19)
7 libobjc.A.dylib 0x000000019203c000 + 28432
8 libobjc.A.dylib objc_destructInstance + 92
9 libobjc.A.dylib object_dispose + 28
10 UIKit -[UIResponder dealloc] + 156
11 UIKit -[UIView dealloc] + 1676
12 SoYoungMobile40 -[SYDiagnoseFloatingView dealloc] (SYDiagnoseFloatingView.m:0)
13 CoreFoundation _common_removeAllObjects + 188
14 CoreFoundation -[__NSArrayM dealloc] + 28
15 libobjc.A.dylib 0x000000019203c000 + 139232
16 UIKit -[UIView dealloc] + 1644
17 libobjc.A.dylib 0x000000019203c000 + 139232
18 UIKit -[UIView dealloc] + 1644
19 libobjc.A.dylib 0x000000019203c000 + 139232
20 UIKit -[UIView dealloc] + 1644
21 UIKit -[UINavigationTransitionView dealloc] + 100
22 libobjc.A.dylib 0x000000019203c000 + 139232
23 UIKit -[UIView dealloc] + 1644
24 UIKit -[UILayoutContainerView dealloc] + 64
25 libobjc.A.dylib 0x000000019203c000 + 139232
26 UIKit -[UIView dealloc] + 1644
27 libobjc.A.dylib 0x000000019203c000 + 139232
28 CoreFoundation _CFAutoreleasePoolPop + 28
29 CoreFoundation ___CFRunLoopRun + 1668
30 CoreFoundation CFRunLoopRunSpecific + 444
31 GraphicsServices GSEventRunModal + 180
32 UIKit -[UIApplication _run] + 684
33 UIKit UIApplicationMain + 208
34 SoYoungMobile40 main (main.m:16)
35 libdyld.dylib _start + 4
I think you add the same observer twice. Always call [scrollView removeObserver:self forKeyPath:keypath context:nil]; before [scrollView addObserver:self forKeyPath:keypath options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];.

KVO observer crash on iOS 11

I’ve a app in App Store which was working fine on iOS 10. But recently I’m getting many crash reports and all logs points to KVO crash and all are happening on iOS 11, below is the crash log.
Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x181e7a858 object_isClass + 16
1 Foundation 0x1836d72bc KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED + 68
2 Foundation 0x1836d5ad0 NSKeyValueWillChangeWithPerThreadPendingNotifications + 300
3 QuartzCore 0x186e35024 -[CALayer setDelegate:] + 108
4 UIKit 0x18c866698 -[UIView dealloc] + 708
5 UIKit 0x18c93f08c -[UILabel dealloc] + 192
6 libobjc.A.dylib 0x181e9a13c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 844
7 UIKit 0x18c86678c -[UIView dealloc] + 952
8 CoreFoundation 0x182b911b4 -[__NSArrayM dealloc] + 140
9 libobjc.A.dylib 0x181e9a13c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 844
10 UIKit 0x18c86678c -[UIView dealloc] + 952
11 libobjc.A.dylib 0x181e9a13c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 844
12 UIKit 0x18c86678c -[UIView dealloc] + 952
13 libobjc.A.dylib 0x181e9a13c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 844
14 UIKit 0x18c86678c -[UIView dealloc] + 952
15 UIKit 0x18cbd3248 -[UINavigationTransitionView dealloc] + 96
16 libobjc.A.dylib 0x181e9a13c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 844
17 UIKit 0x18c86678c -[UIView dealloc] + 952
18 UIKit 0x18cbd319c -[UILayoutContainerView dealloc] + 60
19 libobjc.A.dylib 0x181e9a13c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 844
20 CoreFoundation 0x182b88aac _CFAutoreleasePoolPop + 28
21 UIKit 0x18cc705fc _prepareForCAFlush + 132
22 UIKit 0x18cb555b8 _afterCACommitHandler + 236
23 CoreFoundation 0x182c6a910 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
24 CoreFoundation 0x182c68238 __CFRunLoopDoObservers + 412
25 CoreFoundation 0x182c68884 __CFRunLoopRun + 1436
26 CoreFoundation 0x182b88da8 CFRunLoopRunSpecific + 552
27 GraphicsServices 0x184b6b020 GSEventRunModal + 100
28 UIKit 0x18cb6978c UIApplicationMain + 236
29 MyApp 0x1009bf748 main (main.m:14)
30 libdyld.dylib 0x182619fc0 start + 4
The crashes has crossed over 200 crashes and all are same logs. I’ve not been able to reproduce this crash and kind of stuck on how to proceed next. My entire project is written in objective-C and when I checked there is only one method where I’m using a KVO. Below is a model of my method on how I’ve used it.
-(void)loadData
{
//Some code
if (myAlerts) {
[myAlerts removeObserver:self forKeyPath:#“liveAlerts"];
}
myAlerts = myModel.alerts;
[myAlerts addObserver:self forKeyPath:#"liveAlerts" options:NSKeyValueObservingOptionInitial context:NULL];
}
To remove I use the cleanup method in other viewcontrollers when I no longer need it
-(void)cleanup
{
//Some code
[myAlerts removeObserver:self forKeyPath:#"liveAlerts"];
myAlerts = nil;
}
All the other observers which I've added in my project are NSNotificationCenter observers, could that cause this type of crash log?

Crash in UIKit related to WebView

I have a random crash in UIKit that happend a couple of times already.
It crashes with EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000d
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x30e08f46 objc_msgSend + 5
1 UIKit 0x26d1790d -[_UIWebViewScrollViewDelegateForwarder forwardInvocation:] + 140
2 CoreFoundation 0x23654def ___forwarding___ + 354
3 CoreFoundation 0x23586df8 _CF_forwarding_prep_0 + 24
4 UIKit 0x26b5a6fd -[UIScrollView _getDelegateZoomView] + 84
5 UIKit 0x26b5a635 -[UIScrollView _zoomScaleFromPresentationLayer:] + 24
6 UIKit 0x26b5a5ed -[UIWebDocumentView _zoomedDocumentScale] + 64
7 UIKit 0x26b5a13d -[UIWebDocumentView _layoutRectForFixedPositionObjects] + 104
8 UIKit 0x26b59f97 -[UIWebDocumentView _updateFixedPositionedObjectsLayoutRectUsingWebThread:synchronize:] + 38
9 UIKit 0x26b5c3e5 -[UIWebDocumentView _updateFixedPositioningObjectsLayoutAfterScroll] + 28
10 UIKit 0x26b5c3c1 -[UIWebBrowserView _updateFixedPositioningObjectsLayoutAfterScroll] + 56
11 CoreFoundation 0x2360a281 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
12 CoreFoundation 0x2356652d _CFXNotificationPost + 1784
13 Foundation 0x24296189 -[NSNotificationCenter postNotificationName:object:userInfo:] + 72
14 UIKit 0x27171dd7 -[UIInputWindowController postEndNotifications:withInfo:] + 554
15 UIKit 0x271732ed __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke595 + 368
16 UIKit 0x26b44b05 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 308
17 UIKit 0x26b4471d -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 184
18 UIKit 0x26b4462f -[UIViewAnimationState animationDidStop:finished:] + 66
19 QuartzCore 0x2653d2d9 CA::Layer::run_animation_callbacks(void*) + 236
20 libdispatch.dylib 0x3135c7a7 _dispatch_client_callout + 22
21 libdispatch.dylib 0x3135ffa3 _dispatch_main_queue_callback_4CF + 718
22 CoreFoundation 0x236179d1 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
23 CoreFoundation 0x236160d1 __CFRunLoopRun + 1512
24 CoreFoundation 0x23564211 CFRunLoopRunSpecific + 476
25 CoreFoundation 0x23564023 CFRunLoopRunInMode + 106
26 GraphicsServices 0x2a95d0a9 GSEventRunModal + 136
27 UIKit 0x26b701d1 UIApplicationMain + 1440
28 MY_PROJECT 0x000842cf main (main.m:16)
It looks like it is related to UIWebView, but I have no clue what happened - any help is appreciated
The crash seems to be known in China ...
As mentioned by # NilsHolgerson I had a some issues with notifications.
The most probable reason was a notification that was not properly removed and that did retain a ViewController that was detached otherwise:
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
...
The solution looks as follows:
__weak typeof(self) weakself = self;
__block NSObject *reference = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[[NSNotificationCenter defaultCenter] removeObserver:reference];
...
The deeply reason of this issues is: Container ViewController has been released when webView doing some animations.
So the directly solution is set webView's delegate to nil when ViewControllers dealloc.
Of course if you release VC appropriately as #dogsgod do is also a solution.

How to diagnose crash report

I have a UIViewController:DFUserChatViewController witch is inherit form DFChatViewController,in DFChatViewController init method I have a navigationItem.leftBarButtonItem with a method backAction
- (id)init
{
self = [super init];
if (self)
{
...........
self.navigationItem.leftBarButtonItem = [[[DFBarBackButtonItem alloc] initWithTarget:self action:#selector(backAction:) image:nil] autorelease];
}
return self;
}
in DFUserChatViewController I overwrite the method backAction:
#pragma mark - action
-(void)backAction:(id)sender
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
.............any other thing
.............
{
[self.navigationController popViewControllerAnimated:YES];
}
}
I use crashlytics for crash report and today I receive a crash
0
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x4000000c
raw
0
libobjc.A.dylib objc_msgSend + 5
1
DFmyPro
DFUserChatViewController.m line 349
-[DFUserChatViewController backAction:]
2
UIKit -[UIApplication sendAction:to:from:forEvent:] + 90
3
UIKit -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 30
4
UIKit -[UIControl sendAction:to:forEvent:] + 44
5
UIKit -[UIControl _sendActionsForEvents:withEvent:] + 374
6
UIKit -[UIControl touchesEnded:withEvent:] + 590
7
UIKit -[UIWindow _sendTouchesForEvent:] + 528
8
UIKit -[UIWindow sendEvent:] + 832
9
DFmyPro
DFShakeWindow.m line 46
-[DFShakeWindow sendEvent:]
10
UIKit -[UIApplication sendEvent:] + 196
11
UIKit _UIApplicationHandleEventQueue + 7098
12 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
13
CoreFoundation __CFRunLoopDoSources0 + 206
14
CoreFoundation __CFRunLoopRun + 622
15
CoreFoundation CFRunLoopRunSpecific + 522
16
CoreFoundation CFRunLoopRunInMode + 106
17
GraphicsServices GSEventRunModal + 138
18 UIKit UIApplicationMain + 1136
19
DFmyPro
main.m line 15
main
I run my app again and again ,and didn‘t catch the crash ,How do I know where goes wrong

ios crash issue - EXC_BAD_ACCESS

I got this error message from Crashlytics.
Exception Type: EXC_BAD_ACCESS Code: KERN_INVALID_ADDRESS at 0xd000000c
Thread 0: Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x3b283b26 objc_msgSend + 5
1 TestApp 0x0012b239 -[EasyTableView scrollViewDidScroll:] (EasyTableView.m:291)
2 UIKit 0x339f006d -[UIScrollView(UIScrollViewInternal) _notifyDidScroll] + 64
3 UIKit 0x3376d375 -[UIScrollView setContentOffset:] + 596
4 UIKit 0x3381b005 -[UITableView setContentOffset:] + 320
5 UIKit 0x3376d0e7 -[UIScrollView _adjustContentOffsetIfNecessary] + 1354
6 UIKit 0x33820773 -[UIScrollView(UIScrollViewInternal) _stopScrollingNotify:pin:tramplingDragFlags:] + 414
7 UIKit 0x338205cb -[UIScrollView(UIScrollViewInternal) _stopScrollingNotify:pin:] + 30
8 UIKit 0x33820587 -[UIScrollView removeFromSuperview] + 30
9 UIKit 0x3374e687 -[UIView dealloc] + 366
10 liboainject.dylib 0x002d86cd ___swapMethods_block_invoke_4
11 UIKit 0x3374e687 -[UIView dealloc] + 366
12 liboainject.dylib 0x002d86cd ___swapMethods_block_invoke_4
13 UIKit 0x3374e687 -[UIView dealloc] + 366
14 liboainject.dylib 0x002d86cd ___swapMethods_block_invoke_4
15 libobjc.A.dylib 0x3b285007 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
16 liboainject.dylib 0x002d7d33 __oa__objc_autoreleasePoolPop
17 CoreFoundation 0x30f10a41 _CFAutoreleasePoolPop + 16
18 UIKit 0x337464cd _wrapRunLoopWithAutoreleasePoolHandler + 36
19 CoreFoundation 0x30fa81d5 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
20 CoreFoundation 0x30fa5b79 __CFRunLoopDoObservers + 284
21 CoreFoundation 0x30fa5ebb __CFRunLoopRun + 730
22 CoreFoundation 0x30f10ce7 CFRunLoopRunSpecific + 522
23 CoreFoundation 0x30f10acb CFRunLoopRunInMode + 106
24 GraphicsServices 0x35bfa283 GSEventRunModal + 138
25 UIKit 0x337b2a41 UIApplicationMain + 1136
26 TestApp 0x000ea19d main (main.m:16)
My code (EasyTableView.m: 291) is as below
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([delegate respondsToSelector:#selector(easyTableView:scrolledToOffset:)])
[delegate easyTableView:self scrolledToOffset:self.contentOffset];
}
- (CGPoint)contentOffset {
CGPoint offset = self.tableView.contentOffset;
if (_orientation == EasyTableViewOrientationHorizontal)
offset = CGPointMake(offset.y, offset.x);
return offset;
}
- (void)setContentOffset:(CGPoint)offset {
if (_orientation == EasyTableViewOrientationHorizontal)
self.tableView.contentOffset = CGPointMake(offset.y, offset.x);
else
self.tableView.contentOffset = offset;
}
I tried to debug with Zombie and looked into Leaks of instrument. But I could not found any thing. How can I fix this problem? Thanks in advance
You should clear the scrollView and tableView delegates in dealloc
In Swift :
deinit {
self.scrollView.delegate = nil
self.tableView.delegate = nil
}

Resources