我发现问题出在我的搜索控制器中时,我遇到了一个真正的问题。这是一个带有搜索栏和搜索显示控制器的表格视图。它过去工作正常,但突然间它停止工作。我打开了NSZombieEnabled,它显示我的NSArray名为searchDataSource是僵尸。
当您键入搜索词时,“shouldReloadTableForSearchTerm”会执行handleSearchForTerm函数。 handleSearchForTerm“函数访问我的ProductInfo类,它查询SQLite数据库并返回查询结果。然后将这些结果放在我的searchDataSource数组中。一切似乎在那里工作正常。但是,一旦我进入”cellForRowAtIndexPath“函数,我尝试加载来自searchDataSource的单元格,也就是当我遇到已解除分配的数组的问题时。
以下是搜索控制器的代码:
//
// SearchViewController.h
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface FourthViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate> {
UITableView *mainTableView;
NSArray *searchDataSource;
NSMutableArray *contentsList;
NSMutableArray *searchResults;
NSString *savedSearchTerm;
NSString *webURL;
}
@property (nonatomic, retain) IBOutlet UITableView *mainTableView;
@property (nonatomic, retain) IBOutlet NSArray *searchDataSource;
@property (nonatomic, retain) NSMutableArray *contentsList;
@property (nonatomic, retain) NSMutableArray *searchResults;
@property (nonatomic, copy) NSString *savedSearchTerm;
@property (nonatomic, retain) NSString *webURL;
- (void)handleSearchForTerm:(NSString *)searchTerm;
@end
SearchViewController.m
//
// SearchViewController.m
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import "FourthViewController.h"
#import "ProductsDatabase.h"
#import "ProductInfo.h"
#import "WebViewController.h"
@implementation FourthViewController
@synthesize mainTableView;
@synthesize searchDataSource;
@synthesize contentsList;
@synthesize searchResults;
@synthesize savedSearchTerm;
@synthesize webURL;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.searchDataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Set up the cell...
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row]; //This is where I get the 'message sent to deallocated instance' message.
[cell.textLabel setText:info.sName];
[cell.detailTextLabel setText:info.sType];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row];
webURL = [NSString stringWithFormat:@"http://www.prioritywire.com/specs/%@", info.sFile];
WebViewController *wvController = [[WebViewController alloc] initWithNibName:@"WebViewController" bundle:[NSBundle mainBundle]];
wvController.URL = webURL;
wvController.navTitle = @"Spec Sheet";
[self.navigationController pushViewController:wvController animated:YES];
[wvController release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Save the state of the search UI so that it can be restored if the view is re-created.
[self setSavedSearchTerm:[[[self searchDisplayController] searchBar] text]];
[self setSearchResults:nil];
}
- (void)dealloc {
[searchDataSource release], searchDataSource = nil;
[mainTableView release];
[contentsList release];
[searchResults release];
[savedSearchTerm release];
[super dealloc];
}
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
} else {
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [self contentsList])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
}
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self handleSearchForTerm:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[self setSavedSearchTerm:nil];
self.searchDataSource = nil;
[self.mainTableView reloadData];
}
@end
我对Objective-C很新,无法理解我做错了什么。我花了几天时间试图解决这个问题并且没有运气。我很感激任何人都可以提供帮助。
基思
答案 0 :(得分:1)
这段代码似乎是searchDataSource设置的唯一地方:
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
如果ProductsDatabase
跟随the rules,则您不拥有返回的数组(即它已经自动释放),因此第四行的版本不正确。
答案 1 :(得分:0)
您不是要使用searchResults
- 数组而不是searchDataSource
数组,因为在handleSearchForTerm:
中您要将结果添加到其中。为什么你甚至有searchResult
ivar?它只用在handleSearchForTerm:中,也许有些混淆了吗?