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
(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)
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)
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