2

UPDATE 2

My app is crashing when presenting it modally after a user taps a button in ViewController1. In my storyboard, I have a standard present modally segue set to pop up the UINavController/UITableViewController containing the UISearchBar. That's failing every time.

However, in my AppDelegate, if I set the window's rootViewController to the same UINavController/UITableViewController, everything works as expected.

For some reason transitioning via segue and then acting the UISearchBar is causing the crash.

UPDATE 1

I'm now receiving the following error when tapping one letter:

2015-02-03 12:23:35.262 Afar D[28348:2740681] -[NSNull length]: unrecognized selector sent to instance 0x10e352ce0
2015-02-03 12:23:40.313 Afar D[28348:2740681] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x10e352ce0'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e0a9f35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010dd42bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010e0b104d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010e00927c ___forwarding___ + 988
    4   CoreFoundation                      0x000000010e008e18 _CF_forwarding_prep_0 + 120
    5   CoreFoundation                      0x000000010df89a7b CFStringCompareWithOptionsAndLocale + 219
    6   Foundation                          0x000000010d6822b7 -[NSString compare:options:range:] + 29
    7   UIKit                               0x000000010c5f53b4 -[UIPhysicalKeyboardEvent _matchesKeyCommand:] + 224
    8   UIKit                               0x000000010c53c12e -[UIResponder(Internal) _keyCommandForEvent:] + 285
    9   UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    10  UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    11  UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    12  UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    13  UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    14  UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    15  UIKit                               0x000000010c53c197 -[UIResponder(Internal) _keyCommandForEvent:] + 390
    16  UIKit                               0x000000010c3d8f0a -[UIApplication _handleKeyUIEvent:] + 126
    17  UIKit                               0x000000010c5c7fcc -[UIKeyboardImpl _handleKeyEvent:executionContext:] + 66
    18  UIKit                               0x000000010c75bbb7 -[UIKeyboardLayoutStar completeRetestForTouchUp:timestamp:interval:executionContext:] + 3611
    19  UIKit                               0x000000010c75a8e5 -[UIKeyboardLayoutStar touchUp:executionContext:] + 1374
    20  UIKit                               0x000000010c5d531b __28-[UIKeyboardLayout touchUp:]_block_invoke + 242
    21  UIKit                               0x000000010cb23914 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 332
    22  UIKit                               0x000000010c5d521c -[UIKeyboardLayout touchUp:] + 252
    23  UIKit                               0x000000010c5d5cc6 -[UIKeyboardLayout touchesEnded:withEvent:] + 319
    24  UIKit                               0x000000010c40b308 -[UIWindow _sendTouchesForEvent:] + 735
    25  UIKit                               0x000000010c40bc33 -[UIWindow sendEvent:] + 683
    26  UIKit                               0x000000010c3d89b1 -[UIApplication sendEvent:] + 246
    27  UIKit                               0x000000010c3e5a7d _UIApplicationHandleEventFromQueueEvent + 17370
    28  UIKit                               0x000000010c3c1103 _UIApplicationHandleEventQueue + 1961
    29  CoreFoundation                      0x000000010dfdf551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    30  CoreFoundation                      0x000000010dfd541d __CFRunLoopDoSources0 + 269
    31  CoreFoundation                      0x000000010dfd4a54 __CFRunLoopRun + 868
    32  CoreFoundation                      0x000000010dfd4486 CFRunLoopRunSpecific + 470
    33  GraphicsServices                    0x000000010fc109f0 GSEventRunModal + 161
    34  UIKit                               0x000000010c3c4420 UIApplicationMain + 1282
    35  My App                              0x000000010a5e1c63 main + 115
    36  libdyld.dylib                       0x000000010e75a145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

I'm using iOS8's new UISearchController to manage a UISearchBar for filtering data in a table. If I activate the UISearchBar, the app crashes as soon as I type the first letter (Interestingly, the on-screen keyboard doesn't appear in the Simulator, but I don't think that's related).

In order to narrow things down, I've commented almost everything out of my UIViewController so that the UITableView renders nothing. I've implemented UISearchControllerDelegate and UISearchBarDelegate just so I can log when each method gets called. However, after typing the first letter, I receive no console messages. I don't even know where I could set a breakpoint.

Here's the crash I get:

-[NSNull length]: unrecognized selector sent to instance 0x107602ce0

Note that nowhere in my file am I calling length on anything. Something behind the scenes is, but I can't figure out what.

Here's my code to set up the UISearchController:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;
    self.searchController.definesPresentationContext = true;
    self.searchController.hidesNavigationBarDuringPresentation = false;
    [self.searchController.searchBar sizeToFit];
    self.tableView.tableHeaderView = self.searchController.searchBar;

    self.searchController.searchBar.delegate = self;
    self.searchController.delegate = self;
}

By request, here are my delegate methods (implemented just to see if anything gets called after typing the first letter - they don't):

#pragma mark - UISearchResultsUpdating

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

#pragma mark - UISearchControllerDelegate

- (void)didDismissSearchController:(UISearchController *)searchController
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)didPresentSearchController:(UISearchController *)searchController
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)presentSearchController:(UISearchController *)searchController
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)willDismissSearchController:(UISearchController *)searchController
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)willPresentSearchController:(UISearchController *)searchController
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

#pragma mark - UISearchBarDelegate

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return true;
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return true;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return true;
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}
djibouti33
  • 12,102
  • 9
  • 83
  • 116
  • Are you able to provide delegate code for the search bar? – Lorenzo B Feb 03 '15 at 17:23
  • you are sending a 'length' message to a null object. I would guess something like the text in the search bar is null and something in the controller is trying to read its length. hard to tell without more code on where you set up the search stuff, or the delegate methods – Alex Feb 03 '15 at 17:24
  • Use `self.searchController.definesPresentationContext = YES;` Note that you should use `YES` and `NO` instead of `true` and `false`. – Lorenzo B Feb 03 '15 at 17:37
  • @flexaddicted, I've implemented the UISearchBar delegate methods, and am simply NSLogging the name of the method. However, after typing the first letter in the UISearchBar, the UISearchBarDelegate methods are not getting called. I switched `definesPresentationContext` to true, and that didn't help. – djibouti33 Feb 03 '15 at 17:44
  • Could you add the delegate code? – Lorenzo B Feb 03 '15 at 17:45
  • @Alex, thanks for your feedback, but as I mentioned in the original post, almost everything in my UIViewController class has been commented out except the viewDidLoad above. The UITableView Delegate/Datasource renders an empty table with 0 rows, and my UISearchBarDelegate, UISaerchControllerDelegate, and UISearchResultsUpdating Delegate methods are just logging their method names. However, when typing my first letter, no delegate methods are getting called at all. Also, I'm not calling length on anything anywhere in the file. – djibouti33 Feb 03 '15 at 17:46
  • @flexaddicted, I added the delegate methods above. nothing is called after typing the first letter into the UISearchBar. – djibouti33 Feb 03 '15 at 17:54
  • maybe its this line: self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; you may need to pass in a searchResulstsController for this to work – Alex Feb 03 '15 at 20:10
  • that's supported. from the docs: Set the searchResultsController parameter to nil to display the search results in the same view that you are searching. – djibouti33 Feb 03 '15 at 20:22
  • I just copy and pasted your exact code into a UITableViewController in a sample app and it works fine – Alex Feb 03 '15 at 20:41
  • yup, i basically did the same thing, with positive results. no clue what's going wrong. – djibouti33 Feb 03 '15 at 20:44

2 Answers2

0

NSNull is just a singleton object used to represent null. It is traditionally used to wrap around nil values in containers(arrays and dictionaries) that cannot handle nil entries.

This error often comes up when parsing json and trying to add the result in a collection.

Are you doing something like this in your delegate method(s)?

Edit: Judging by the message you are sending to that NSNull (length), you probably get an "empty" result for a string you asked for and expected not be nil.

joakim
  • 3,533
  • 2
  • 23
  • 28
  • Thanks for the tip, but in order to reduce all complexity, I've basically commented out everything in my code but the viewDidLoad (above), the required TableView delegate/datasource methods (which renders an empty table with 0 rows), and all of the UISearchBarDelegate, UISearchController Delegate, and UISearchResultsUpdating delegate methods. All of those methods are simply logging their method name. Nowhere in my file is length being called on anything, and after typing the first letter, no delegate methods are getting called (evident by the fact that nothing is in my console) – djibouti33 Feb 03 '15 at 17:50
  • Then the next step would be to search for NSStrings in your table view. Particularly UILabel instances. What if you remove them? Are you holding weak references to any of them? – joakim Feb 03 '15 at 18:05
  • I've commented everything out from my table view datasource/delegate methods, so no cells are appearing on screen. there are no strings in my file either. weird. – djibouti33 Feb 03 '15 at 19:09
0

After burning an entire day struggling with this, it came down to a totally unrelated problem: a corrupted storyboard.

This SO question recommended finding which scene was corrupt and recreating it. Unfortunately there was no way for me to determine that, so after some trial and error, it ended up being the initial view controller in my storyboard, which happened to be a UINavigationController. I deleted that, added it back in, and everything is golden.

Community
  • 1
  • 1
djibouti33
  • 12,102
  • 9
  • 83
  • 116