0
votes

This is the code for my SearchViewController. But when I push to the nextController, the app crashes and it doesn't reach nextController, or in some cases I get a glance at it before crash. I recieve an error "bad instance sent to selector" in log. The SearchViewController has a NavigationController attatched in storyboard, and I push through the navigation controller as you see.

If I change 'pushViewController' to 'presentModalViewController' , it's now able to load the UITableViewController, but it now crashes if I scroll(swipe) the TableView if it's populated with results. If it's empty (no matching results) it's not crashing. Weird. Also, no navigation bar above TableView.

Can you tell me what I'm doing wrong and help me correct it? Got a feeling it's an easy issue.

SearchViewController.h

#import <UIKit/UIKit.h>

@interface SearchViewController : UIViewController

@property (nonatomic, strong) NSMutableArray *allObjectsArray;
@property (nonatomic, strong) NSMutableArray *resultObjectsArray;

@property (nonatomic, strong) IBOutlet UITextField *nameTextField;


-(IBAction)searchButtonPressed:(id)sender;

@end

SearchViewController.m

-(IBAction)searchButtonPressed:(id)sender{  


    NSString *path = [[NSBundle mainBundle] pathForResource:@"Wine" ofType:@"plist"];
    allObjectsArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

    NSString *nameString = [NSString stringWithFormat:@"%@", [nameTextField text]];

    resultObjectsArray = [NSMutableArray array];
    for(NSDictionary *wine in allObjectsArray)
    {
        NSString *wineName = [wine objectForKey:@"Name"];
        NSRange range = [wineName rangeOfString:nameString options:NSCaseInsensitiveSearch];
        if(range.location != NSNotFound)
        [resultObjectsArray addObject:wine];
    }

NSLog(@"Objects: %@", allObjectsArray);

ResultsTableViewController *nextController = [[self storyboard] instantiateViewControllerWithIdentifier:@"ResultsController"];

nextController.objectsArray = [[NSMutableArray alloc]initWithArray:resultObjectsArray];

NSLog(@"Results: %@", nextController.objectsArray);
[self.navigationController pushViewController:nextController animated:YES];
[nextController release];
}

and this is objectsArray in nextController which populates the UITableView:

@property (nonatomic, strong) NSMutableArray *objectsArray;

ResultsTableViewController.m:

#import "ResultsTableViewController.h"

@interface ResultsTableViewController ()

@end

@implementation ResultsTableViewController

@synthesize objectsArray;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
 NSLog(@"%s", __FUNCTION__);

// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;

// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [objectsArray count];
NSLog(@"%s", __FUNCTION__);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%s", __FUNCTION__);
static NSString *CellIdentifier = @"searchResultCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    // Use the default cell style.
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"searchResultCell"] autorelease];
}


// Configure the cell...
cell.textLabel.text = [[objectsArray objectAtIndex:indexPath.row] valueForKey:@"Name"];

return cell;
}

@end
1
I'm going to assume you meant "unrecognized selector sent to instance" rather than the other way around? Also, is there any additional information with the error message in the console?Alexis King
what about the actual tableview code? could you please post it?Miro Hudak
Just a detail, but I would rather use self.objectsArray to use the property directly -- if i remember my obj-c correctly, objectsArray accesses the class member and not obj-c property, which in case of non-ARC code could cause some memmgt problems...Miro Hudak
BTW, are you using or are you not using ARC? Because, you have some [UIViewController release] there...Miro Hudak
@KristofferBilek check my edit below on "disabling ARC to let something other to compile"... may be useful for you.Miro Hudak

1 Answers

1
votes

(posting as an answer - see details in comments of the question)

Are you using or are you not using ARC? Because, you have some [UIViewController release] there...

(as for the self.objectsArray)

cell.textLabel.text = [[self.objectsArray objectAtIndex:indexPath.row] valueForKey:@"Name"];
  • and on the other occasions. then, you'll assure to use property getter... the same with setting the value; self.objectsArray = ...; but only, when you are accessing the property; provided, you have it properly @synthesize-d

(and one more thing, just a nit-picking)

cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  • use constants as identifiers as much as possible, definitelly when you already have it defined in scope

Btw, I've just noticed, you wrote "you've just deactivated the ARC for some other code to work"... you don't have to, you can disable ARC on per file basis; and if you don't have memory management and obj-c experience, just don't disable ARC when you have it. It's a nice addition to iPhone Obj-C... refer to my post on how to per-class disable ARC: Adding UIActivityIndicator to UITableView