SIGABRT between loadView and viewDidLoad - ios

I'm new to iOS development, and having trouble identifying the source of a SIGABRT. I've narrowed it down to something that happens during initialization of a UIViewController subclass, specifically between its loadView and viewDidLoad methods.
I narrowed it down with an NSLog call in each of those method overloads in my UIViewController subclass. However, I'm unable to get any more granularity from the debugger; I can't step into the [super loadView] method. Are there any techniques for debugging a SIGABRT other than NSLogs and stepping through with the debugger? Is there any way to see exactly from where the exception was thrown?
Program-specific details
This program uses Core Data; I created it following this tutorial. I believe the SIGABRT started happening after I ran through the "Relationships In Action" section, and was not happening before (I think I had a successful build at the end of the preceding section). Specifically, I can successfully add a Person, but PersonDetailTableViewController throws a SIGABRT between loadView and viewDidLoad.
I've tried deleting the app from the iPhone simulator, and also running a Product > Clean; neither had any effect.

Found the culprit. I had earlier incorrectly created an IBOutlet by ctrl+dragging from a Table View Cell's Text Field into my UITableViewController subclass. I manually deleted the code this created, but a connection remained in the Connections Inspector. Deleting that connection solved the problem -- no more SIGABRT.
It's unfortunate that Xcode sees the problem (see the exclamation mark in the attached image), but didn't tell me about it in any way except the mysterious SIGABRT....

Related

iOS IBOutlet is non-nil, somehow being scavenged to nil

TL;DR: I have an IBOutlet (UILabel) that is properly connected in Storyboard. Accessing (unwrapping) it works fine in viewDidLoad() ... but a few seconds later its value is nil. A watchpoint says that the outlet changes right after a call to viewDidLayoutSubviews(), but... a print() call at the end of viewDidLayoutSubviews() shows it non-nil.
This is very similar to IBOutlet is nil but his solution (track value with didSet()) did not work. (There are many related posts but all had trivial solutions.)
What I have done:
Reconnected the outlet to the Label — from both sides
Deleted the Label and reconnected it
Cleaned the project
Deleted the DerivedData
Quit and restarted Xcode
Quit and restarted my Mac
Added a didSet() method to the outlet.
It triggers during viewDidLoad() and shows a non-nil value.
In viewDidLoad() I set its text value with no problem
It does not trigger before the nil-unwrapping crash
Added a watchpoint to the variable.
This does trigger before crash (right after viewDidLayoutSubviews() and shows the following:
As mentioned before, at exit of the most recent method call before the watchpoint (viewDidLayoutSubviews()) the outlet is non-nil.
These crashes seem always to involve subviews of a particular superview. I added a watchpoint to the superview's outlet but it never triggers.
What could be inciting my code to let go of this weak reference?
TL;DR: I was clobbering the relevant views.
Well, the best way to find your own answer is to ask someone else. Thanks to #DonMag, I was preparing more traces, breakpoints, and screen shots. I noticed this method (added to fix another bug, of course):
Of course, the two views that were becoming nil were subviews of centralOverlay. Ones I wanted to keep.
So I guess my answer was similar to that of IBOutlet is nil — pilot error — except the didSet() handler did not solve the mystery.

iOS xib file IBOutlet not recognized - (class not key-value coding compliant)

I am running XCode 7.1 and running on device(iOS 9) - (not simulator). I am loading up a nib file by name as such:
MyDetailsViewController *myDetailsVC = [MyDetailsViewController initWithNibNamed:#"MyDetails" withNotificationCenter:notificationCenter];
this is simply just a class method that i have set up that loads up the xib via the mainBundle. The xib file is just a UIView with a tableview inside of it everything seems to be hooked up properly. However, when loading the nib(viewWillAppear, viewDidLoad etc hasn't executed yet) from the bundle I get the error:
NSUnknownKeyException, reason: '[MyDetailsViewController setValue:forUndefinedKey:]:This class is not
key value coding-compliant for the key tableView'
I know that I am not getting back some generic view controller because it spells out very clearly what view controller we are talking about. The File Owner seems to be hooked up properly and its Custom Class is set to MyDetailsViewController. Even when I hover over the IBOutlet 'circle' in code the tableview highlights as well as when i hover over the menu when checking the outlets.
Something that may be totally unrelated is the internal error message in the xib file, it may or may not be related to my problem and i've never seen it before. The beginning of the log file that you get from that error is:
Can anyone help me determine what is going on here? I would appreciate it.
here are a few more screenshots:
Before init you should call alloc first:
// MyDetailsViewController *myDetailsVC = [MyDetailsViewController initWithNibNamed:#"MyDetails" withNotificationCenter:notificationCenter];
MyDetailsViewController *myDetailsVC = [[MyDetailsViewController alloc] initWithNibNamed:#"MyDetails" withNotificationCenter:notificationCenter];

Crash when tapping on UITextField or UITextView: Assertion failure in -[UICalloutBarButton layoutSublayersOfLayer:]

Answers to similar questions did not help so I'm opening a new question.
I have this issue in several of my projects now:
Tapping on the first responder UITextField or on a UITextView (that would normally bring up the default context menu for copy and paste) causes my app(s) to crash.
Note: UICalloutBarButton is a UIKit private API, so there is no chance to change its layoutSubviews implementation and call [super layoutSubviews] in it.
Log message:
*** Assertion failure in -[UICalloutBarButton layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UICalloutBarButton's implementation of -layoutSubviews needs to call super.'
I don't have any idea why this appears. Would be very happy for any help.
EDIT
Trying to reproduce the crash in a demo project I found out that it is a custom UIView category that causes the crash. See accepted answer for more details.
By trying to reproduce the crash in a demo project I found out that it is a custom UIView category that causes the crash.
When creating this fault, I assumed that category methods were only available for UIView subclasses that #import this category.
But this is not the case as described in the Apple Documentation:
Any methods that you declare in a category will be available to all instances of the original class, as well as any subclasses of the original class. At runtime, there’s no difference between a method added by a category and one that is implemented by the original class.
So not being aware of this, I had overridden in my custom category the UIView method + (BOOL) requiresConstraintBasedLayout to return YES (like I wrongly thought only for those classes that import this category).
Putting a breakpoint in that method, I learned that this 'category-method' gets called from everywhere in the UIKit once the category files are added to a project.
Nothing but a painful way of learning/accepting, that overriding methods in categories is never a good idea - unless you want to cause strange crashes like this ;-).
Sorry for stealing your time, but thank you for asking some code examples which forced me to seriously reproduce the problem - which lead me to the crash-cause...

Add a UITableView as a subview crash only on simulator iOS

Is there a problem with adding a UITableView as a subview of aUIView? I had a line of code that was working for months, and recently broke after I updated XCode to 4.6.3. Long story short, I was returning TableViewTwo as a subview of a UIView as a footer of TableViewOne. Please don't ask me why this is necessary, it is just convenient for what I am doing. Well, the app would always crash on the simulator, but not on the device. It would give me a bizarre error and an opaque call stack. The error said unrecognized selector(numberOfSections)sent to instance. Yes, the selector was numberOfSections and not the numberOfSectionsInTableView in the UITableViewDataSource. Well, when I returned the UITableViewTwo as UITableViewOne's footer..everything started working. Does anyone know if there is a problem with adding a UITableView as a subview of a UIView? For more information - see this SO Post(link)

UITableViewCell getting _accessibilityUpdateRemoveControl on deallocated instance

Edit: While my comments have an iOS 5 working example, I am still getting this for other versions. I've now implememted a test to only register and dequeue cells if iOS 5, but it's really puzzling!
still receiving _accessibilityUpdateRemoveControl exceptions, strange nuisance, appears to be something with the edit controls, nothing is retained so nothing needs deallocing, but will try, and post the answer if I find it!
This was working yesterday, and now it's not... I changed nothing!
Edit: Turns out, while reloadData causes the crash, the crash does not occur without my custom tableViewCell... hmmm, something about removing the + sign, but it doesn't happen with deletion!
Actual error is this:
[CustomTableViewCell _accessibilityUpdateRemoveControl]: message sent to deallocated instance.
What's funny is, the remove button works. Essentially it removes the item from an array, adds it to another, basically putting it "to another table". No crashing, works fine.
If I remove the line that reloads the data in the table, after the insert button adds it, it also works. Eg: Don't immediately reload the data, close window, come back, everything displays fine. The exact line, so far, that crashes it is in
[theTable reloadData], but that line, for the other table (as I update both) doesn't crash at all. Actually, thanks to that, I'm gonna view the headers for UITableView's functions, and view other answers with that specific line. I just didn't see this, anywhere, after searching for that weird function call.
I'm ensuring my cell is within memory, and even quit dequeuing just to ensure it's working. I'm stumped with this, hopefully will have solution in an hr or less.
Thanks
I stepped through Apple's code, line by line, read the name of every function and noticed this:
editControlWasClicked: (id) clicked
is called just before crashing. I combined that with the error message, and the fact I call [table2 reloadData] before this is called, and pieced those pieces together.
The cell is erased (so it moves to the other table), but somehow calls its system callBack "editControlWasClicked" after the table reloads... since it's on the main thread, I'm guessing the table stuff is multi-threaded... how else would it call these in order but do that After the reload??
So to test this, I used the "afterDelay" function, and low and behold, it worked.
You may be asking why I'm using an add edit control in one and subtract in the other... there is a purpose to that.
So, possible solutions: 1) use the afterDelay method of selectors.
2) Write a custom IBAction ('cause it's a xib) or otherwise use custom images and functions to ensure that doesn't get called back.
Note, 2 involves writing an extra delegate so that messages from the cell can reach the view controller.
Basic solution: use iOS 5, use the queuing, otherwise do one of the above solutions or figure out the threading/hooks and find a way to do this without delaying. (I would prefer such if I can find it)

Resources