Apteligent crash monitoring for mobile apps allows developers to better understand the root causes of fatal exceptions and errors. Thousands of developers rely on Apteligent for real-time actionable performance data, giving us a broad perspective on some of the issues that plague apps and frustrate developers. We recently analyzed the most frequent crashes on iOS and found that the vast majority (over 75%) of all crashes on iOS can be categorized as follows:
1. SIGSEGV
SIGSEGV is a signal (SIG) sent to interrupt the code when a segmentation violation (SEGV) occurs. This is the most common crash on iOS, constituting nearly 50% of all crashes — partially due to its generic nature. This signal occurs when your app attempts to access memory that has not been allocated by the program (or memory that has recently been freed).
To debug a SIGSEGV crash, look for variables that have been deallocated then accessed from somewhere else.
A common cause is a dangling delegate or listener that has been deallocated.
// myView can, and should be, a weak reference
self.delegate = myView;
// myView gets popped from the UINavigationController and is deallocated but
// self.delegate is still set - and now points nowhere
[self.delegate doSomething]; // will throw a SIGSEGV error
To resolve this, simply check that the delegate can respond to the given selector:
if([self.delegate respondsToSelector:@selector(doSomething)]) {
[self.delegate doSomething];
}
2. NSInvalidArgumentException
The first few lines of the stack trace can usually point you in the right direction to track down this exception. One of the most common causes is shown in the stack trace as an unrecognized selector. This crash occurs when a method is being called on an object that can’t respond to it. For example:
// Since the object doesn’t respond to the method provided, this
// will throw an unrecognized selector NSInvalidArgumentException
[@"myString" objectForKey:@"someKey"];
This obvious coding error won’t make it past the compiler, so keep an eye out for dynamic assignments like JSON deserialization:
// data => ['item0', 'item1', 'item2']
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
// json data is an array, not a dictionary
// will throw an NSInvalidArgumentException because it is passing
// an NSArray when an NSDictionary is expected
[json objectForKey:@"myKey"];
3. SIGABRT
This signal (SIG) is an abort (ABRT) message that stops the program. You’ll see this in your debugger when there is an unhandled exception (see #2). However, in a deployed app SIGABRT appears when there is an assertion failure or abort method called within the app or the operating system.
SIGABRT codes are often raised during asynchronous system method calls, so keep an eye out for CoreData, accessing files, NSUserDefaults, and other multithreaded system functions.
Read more about the above crash types and two more common crashes—SIGBUS and NSRangeException—on the Apteligent blog. Apteligent gives you full insight into all performance issues that impact optimal user experience. It takes one line of code to get started on the Apteligent platform and start collecting performance data for your app. Check out the additional capabilities of our solution here.
Thanks to Apteligent for sponsoring appcoda.com this week, and Chris Beauchamp for writing this post! This content is sponsored via Syndicate Ads.